Fedora Account System
Red Hat Associate
Red Hat Customer
AI_ONLY_REPORT package: sssd-2.12.0-1.el10 ------ Summary: OOB Read in `sss_auth_unpack_passkey_blob` from Unbounded Parsing of `SSS_AUTHTOK_TYPE_PASSKEY_KRB`: a malformed length-delimited passkey blob that omits required in-bounds NUL terminators can be parsed past the provided buffer, causing a locally triggerable out-of-bounds read and likely denial of service in the SSSD PAM responder. Requirements to exploit: Local access to a system using the SSSD PAM responder, plus the ability to submit a crafted `SSS_AUTHTOK_TYPE_PASSKEY_KRB` blob without in-bounds NUL terminators. The available code context indicates this parsing occurs during PAM request handling before later trust-based restrictions, so ordinary local triggering appears plausible in default deployments. Component affected: `sssd-2.12.0-1.el10`, `src/util/authtok.c`, `sss_auth_unpack_passkey_blob()`; attacker-controlled ingress is via the PAM responder path in `src/responder/pam/pamsrv_cmd.c` Version affected: `sssd-2.12.0-1.el10` 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:N/UI:N/S:U/C:N/I:N/A:H - 5.5 (MEDIUM) AV:L - Exploitation requires local access to a system that can reach the SSSD PAM responder. AC:L - The malformed input is straightforward: the attacker supplies a passkey blob with missing in-bounds `'\0'` terminators. PR:N - Available evidence indicates the PAM responder socket is intended to be reachable by ordinary local PAM clients and the affected parsing occurs before trust-based restrictions; deployments that further restrict local access may reduce exposure. UI:N - No separate user interaction is required once the crafted request is sent. S:U - The impact is confined to the vulnerable SSSD component. C:N - No confidentiality impact is established from the available evidence. I:N - No integrity impact is established from the available evidence. A:H - The demonstrated outcome is an out-of-bounds read that can crash or destabilize the authentication responder path. Impact: Moderate. Based on Red Hat's severity guidance, this issue has a credible local availability impact in a core authentication component, but the established effect is not remote, does not show privilege escalation, and does not demonstrate system compromise or arbitrary code execution. That makes it more serious than Low, but not a fit for Important or Critical. Embargo: no Reason: The current evidence supports a local denial-of-service issue with no demonstrated confidentiality, integrity, or code execution impact, and moderate/low issues of this type typically do not require embargo handling. Acknowledgement: Aisle Research Vulnerability Details: `sss_auth_unpack_passkey_blob()` parses a passkey blob as a sequence of C strings, but it receives only `const uint8_t *blob` and no length parameter. The function therefore trusts in-band `'\0'` terminators and walks past the caller-provided buffer if they are missing. ```c errno_t sss_auth_unpack_passkey_blob(TALLOC_CTX *mem_ctx, const uint8_t *blob, char **_prompt, char **_key, char **_pin) { size_t len = 0; ... prompt = talloc_strdup(mem_ctx, (const char *) blob + len); len += strlen(prompt) + 1; key = talloc_strdup(mem_ctx, (const char *) blob + len); len += strlen(key) + 1; ... } ``` `extract_authtok_v2()` accepts `auth_token_data` together with `auth_token_length`, and the `SSS_AUTHTOK_TYPE_PASSKEY_KRB` path passes that length into `sss_authtok_set_passkey_from_blob(tok, data, len)`. However, `sss_authtok_set_passkey_from_blob()` then calls `sss_auth_unpack_passkey_blob(tmp_ctx, data, &prompt, &key, &pin);`, so the explicit length is discarded before parsing. By contrast, `sss_auth_unpack_2fa_blob()` and `sss_auth_unpack_sc_blob()` both take `blob_len` and validate bounds. The available materials establish an out-of-bounds read and a realistic responder crash. An information disclosure effect is theoretically possible for this bug class, but no practical disclosure path is demonstrated here, so the supported impact is local denial of service. Steps to reproduce: 1. Build `sssd-2.12.0-1.el10` with AddressSanitizer enabled, for example with `-fsanitize=address`. 2. Add a cmocka test under `src/tests/cmocka/test_authtok.c` that calls `sss_authtok_set(tok, SSS_AUTHTOK_TYPE_PASSKEY_KRB, blob, blob_len)`. 3. Use a blob with no `'\0'` inside `blob_len`, for example `{ 't','r','u','e','K','E','Y','D','A','T','A' }` with `blob_len = 11`. 4. Run the affected unit test. 5. Observe an ASan invalid read originating from `strlen()`/`talloc_strdup()` in `sss_auth_unpack_passkey_blob()`. This reproducer uses only local code paths and does not depend on external services. Mitigation: No complete runtime mitigation is established from the available information. Until a fixed package is available, reducing access to the local PAM responder interface to trusted users can lower exposure where that is operationally possible, but default responder permissions are designed to allow ordinary local PAM clients. Proposed Fix: Pass the blob length into `sss_auth_unpack_passkey_blob()` and replace unbounded string parsing with `memchr()`-bounded extraction so the passkey parser behaves like the other bounded blob unpackers. ```diff diff --git a/src/util/authtok.c b/src/util/authtok.c index 0000000..0000000 100644 — a/src/util/authtok.c +++ b/src/util/authtok.c @@ -690,21 +690,43 @@ errno_t sss_auth_unpack_passkey_blob(TALLOC_CTX *mem_ctx, const uint8_t *blob, + const uint8_t *blob, size_t blob_len, char **_prompt, char **_key, char **_pin) { size_t len = 0; + const uint8_t *p = blob; + size_t rem = blob_len; + const uint8_t *end; + size_t flen; char *prompt; char *key; char *pin; prompt = talloc_strdup(mem_ctx, (const char *) blob + len); + if (blob == NULL || _prompt == NULL || _key == NULL || _pin == NULL) { + return EINVAL; + } + + end = memchr(p, '\0', rem); + if (end == NULL) return EINVAL; + flen = (size_t)(end - p); + prompt = talloc_strndup(mem_ctx, (const char *)p, flen); if (prompt == NULL) return ENOMEM; len += strlen(prompt) + 1; + p += flen + 1; rem -= flen + 1; key = talloc_strdup(mem_ctx, (const char *) blob + len); + end = memchr(p, '\0', rem); + if (end == NULL) { talloc_free(prompt); return EINVAL; } + flen = (size_t)(end - p); + key = talloc_strndup(mem_ctx, (const char *)p, flen); if (key == NULL) { talloc_free(prompt); return ENOMEM; } len += strlen(key) + 1; + p += flen + 1; rem -= flen + 1; if ((strcasecmp(prompt, "true") == 0)) { pin = talloc_strdup(mem_ctx, (const char *) blob + len); + end = memchr(p, '\0', rem); + if (end == NULL) { + talloc_free(prompt); + talloc_free(key); + return EINVAL; + } + flen = (size_t)(end - p); + pin = talloc_strndup(mem_ctx, (const char *)p, flen); if (pin == NULL) { talloc_free(prompt); talloc_free(key); @@ -792,7 +814,7 @@ static errno_t sss_authtok_set_passkey_from_blob(struct sss_auth_token *tok, ret = sss_auth_unpack_passkey_blob(tmp_ctx, data, &prompt, &key, &pin); + ret = sss_auth_unpack_passkey_blob(tmp_ctx, data, len, &prompt, &key, &pin); @@ -854,7 +876,8 @@ errno_t sss_authtok_get_passkey(TALLOC_CTX *mem_ctx, ret = sss_auth_unpack_passkey_blob(mem_ctx, tok->data, &prompt, &key, &pin); + ret = sss_auth_unpack_passkey_blob(mem_ctx, tok->data, tok->length, + &prompt, &key, &pin); ``` ------ This report was generated using AI technology. Always review AI-generated content prior to use