Fedora Account System
Red Hat Associate
Red Hat Customer
AI_ONLY_REPORT package: sssd-2.12.0-1.el10 ------ Summary: Unbounded Per-Connection Memory Growth in KCM via GET_CRED_UUID_LIST / DESTROY: a local client can retain stale credential objects in a long-lived KCM connection and exhaust responder memory through repeated `STORE` / `GET_CRED_UUID_LIST` / `DESTROY` cycles. Requirements to exploit: The KCM responder must be enabled and reachable, and a local user able to connect to the KCM UNIX socket must keep one client connection alive while repeatedly issuing normal KCM requests against a ccache. Component affected: `sssd-2.12.0-1.el10` KCM responder credential-table handling in `src/responder/kcm/kcmsrv_ops.c` and `src/responder/kcm/kcmsrv_ops.h` (`kcm_creds_to_table()`, `GET_CRED_UUID_LIST`, `GET_CRED_BY_UUID`, and `DESTROY`). Version affected: `sssd-2.12.0-1.el10` when the KCM responder is enabled and reachable by a local client Patch available: no released package fix established; proposed patch included below Version fixed: unknown Upstream coordination: Not notified. CVSS: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H - 5.5 (MEDIUM) AV:L - Exploitation requires local access to the host and the KCM responder socket. AC:L - Once KCM is reachable, the issue is triggered with a straightforward request loop and no unusual preconditions. PR:L - A local account or equivalent local execution context is needed to connect and send requests. UI:N - No victim interaction is required. S:U - The impact is confined to the KCM responder's own security scope. C:N - The available evidence does not show unauthorized disclosure of credential data. I:N - The issue is stale object retention and memory exhaustion, not unauthorized data modification. A:H - Memory can grow without bound for the life of a maintained connection, leading to denial of service. Impact: Moderate. The issue can cause a real availability loss by exhausting KCM responder memory for deployments that rely on KCM, but exploitation is local and depends on KCM being enabled and reachable. The available evidence does not support confidentiality, integrity, privilege-escalation, or remote-compromise impact, which places the issue below Important or Critical under Red Hat's severity guidance. Embargo: no Reason: This is a local, availability-only denial of service with straightforward operational mitigations and no evidence of confidentiality, integrity, or system-compromise impact. Acknowledgement: Aisle Research Vulnerability Details: The KCM responder keeps a per-connection credential cache in `conn_data->creds`. The helper below creates that table if needed, adds or replaces entries by UUID, and reparents each credential under the table with `talloc_steal()`, but it does not remove credentials that disappeared from backend state: ```c struct kcm_conn_data { /* Credentials obtained by GET_CRED_UUID_LIST. We use to improve performance by avoiding ccache lookups in GET_CRED_BY_UUID. */ hash_table_t *creds; }; ... static errno_t kcm_creds_to_table(TALLOC_CTX *mem_ctx, struct kcm_cred *creds, hash_table_t **_table) { char str[UUID_STR_SIZE]; uuid_t uuid; errno_t ret; if (*_table == NULL) { *_table = sss_ptr_hash_create(mem_ctx, kcm_creds_table_delete_cb, NULL); if (*_table == NULL) { return ENOMEM; } } for (struct kcm_cred *crd = creds; crd != NULL; crd = kcm_cc_next_cred(crd)) { ... ret = sss_ptr_hash_add_or_override(*_table, str, crd, struct kcm_cred); if (ret != EOK) { return ret; } talloc_steal(*_table, crd); } return EOK; } ``` `GET_CRED_UUID_LIST` and `GET_CRED_BY_UUID` both repopulate this same connection-scoped table by calling `kcm_creds_to_table(conn_data, kcm_cc_get_cred(cc), &conn_data->creds);`. In the available `DESTROY` path, the backend ccache is deleted and the operation returns success, but no corresponding clear or prune of `conn_data->creds` is shown. As a result, stale `kcm_cred` objects can remain reachable for the lifetime of the client connection even after the backend ccache is removed. Repeating `STORE`, `GET_CRED_UUID_LIST`, and `DESTROY` on one kept-alive connection therefore causes per-connection responder memory growth that is not reclaimed until connection teardown or responder restart. Steps to reproduce: 1. Start the KCM responder and connect to `/var/run/.heim_org.h5l.kcm-socket` using one persistent client connection. 2. Create or select a ccache name on that same connection. 3. `STORE` a credential blob so a new credential UUID is added. 4. Call `GET_CRED_UUID_LIST` for that ccache so `conn_data->creds` is populated. 5. Call `DESTROY` for the same ccache. 6. Verify backend deletion succeeds, for example by observing a successful `DESTROY` result and that the ccache is no longer returned on re-query. 7. Repeat steps 2 through 6 on the same kept-alive connection, continuing to send requests so the connection is not dropped as idle. 8. Observe that the KCM process RSS continues to grow and does not return to baseline until the connection is closed or the responder is restarted. Mitigation: Restrict access to the KCM responder to trusted local users where deployment policy permits, and disable KCM on systems that do not require it. If abnormal memory growth is observed, closing abusive client connections or restarting the responder reclaims the retained connection-scoped memory, but these are operational workarounds rather than a fix. Proposed Fix: Rebuild the per-connection credential table from current backend state on each refresh so stale credentials are released instead of accumulating across a long-lived connection. ```diff diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c — a/src/responder/kcm/kcmsrv_ops.c +++ b/src/responder/kcm/kcmsrv_ops.c @@ -1098,6 +1098,12 @@ kcm_creds_to_table(TALLOC_CTX *mem_ctx, uuid_t uuid; errno_t ret; + /* Rebuild from current backend view to avoid retaining stale credentials + * across long-lived client connections. + */ + talloc_zfree(*_table); + *_table = NULL; + if (*_table == NULL) { *_table = sss_ptr_hash_create(mem_ctx, kcm_creds_table_delete_cb, NULL); if (*_table == NULL) { ``` An alternative implementation would be to prune UUIDs that are no longer present in the current `cc->creds` set before returning the refreshed table. ------ This report was generated using AI technology. Always review AI-generated content prior to use