Fedora Account System
Red Hat Associate
Red Hat Customer
AI_ONLY_REPORT package: sssd-2.12.0-1.el10 ------ Summary: Local Out-of-Bounds Read in PAM v1 Parser (`pam_parse_in_data`) Causing Potential DoS: a local client that negotiates protocol v1 and sends an empty or truncated PAM request body can trigger an out-of-bounds read and may terminate the PAM responder, resulting in local denial of service. Requirements to exploit: Local access to the PAM responder UNIX socket, the ability to negotiate protocol v1 with `SSS_GET_VERSION`, and the ability to send a malformed `SSS_PAM_AUTHENTICATE` request body. No user interaction is required. If a deployment restricts PAM socket access more tightly than common configurations, practical exploitability is reduced. Component affected: `sssd-2.12.0-1.el10` PAM responder in `src/responder/pam/pamsrv_cmd.c`, function `pam_parse_in_data()` 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:L - 3.9 (LOW) AV:L - The issue is reachable only from a local client that can connect to the PAM responder UNIX socket. AC:L - Triggering the flaw requires only a malformed protocol v1 request body such as an empty or truncated message. PR:N - The vulnerable parser path itself does not require prior authentication, and common PAM socket deployments allow local clients to reach it; stricter socket ACLs would reduce practical risk. UI:N - No human interaction is needed once local socket access is available. S:U - The impact remains within the PAM responder's own security scope. C:N - The available evidence shows an out-of-bounds read, but not disclosure of sensitive data. I:N - No data modification, privilege gain, or integrity impact is established. A:L - The demonstrated outcome is potential local denial of service, but the available evidence does not show a consistently reliable high-impact crash in every malformed-input case. Impact: Moderate. This is a real local memory-safety flaw in a security-sensitive authentication responder, and malformed v1 requests can affect service availability. However, the available evidence supports local denial of service only, with no demonstrated confidentiality or integrity impact, and the failure appears less than maximally reliable, which places it below Red Hat's Important classification. Embargo: no Reason: The issue is local-only, the demonstrated impact is limited to availability, and the remediation is straightforward. Based on Red Hat guidance, this does not appear to require embargoed handling. Acknowledgement: Aisle Research Vulnerability Details: In the PAM responder's protocol v1 parser, `pam_parse_in_data()` computes `last = blen - 1` before validating `blen`, then repeatedly dereferences `body[end++]` without first proving `end < blen`. This creates two supported failure modes: `blen == 0` underflows `last` to `SIZE_MAX`, and truncated v1 string fields can advance `end` to or beyond the end of the supplied body before the terminator check occurs. ```c static int pam_parse_in_data(struct pam_data *pd, uint8_t *body, size_t blen) { size_t start; size_t end; size_t last; int ret; last = blen - 1; end = 0; /* user name */ for (start = end; end < last; end++) if (body[end] == '\0') break; if (body[end++] != '\0') return EINVAL; pd->logon_name = (char *) &body[start]; ... } ``` The same unchecked `body[end++]` pattern is then repeated while parsing `service`, `tty`, `ruser`, and `rhost`. Protocol version 1 remains registered, and the request dispatch path still selects `pam_parse_in_data()` when v1 is negotiated, so the vulnerable parser remains reachable through the PAM responder. Based on the available evidence, the expected security effect is an out-of-bounds read that may cause responder termination or restart behavior depending on build hardening and runtime supervision; code execution, data disclosure, and privilege escalation are not established. Steps to reproduce: 1. Build or run the package with ASAN enabled, or run the PAM responder under a debugger. 2. Connect to the PAM responder UNIX socket, typically `/var/lib/sss/pipes/pam` in standard deployments. 3. Send `SSS_GET_VERSION` (`0x0001`) with body `uint32(1)` to negotiate protocol v1. 4. On the same connection, send `SSS_PAM_AUTHENTICATE` (`0x00F1`) with either an empty body (`blen == 0`) or a truncated v1 body that omits one or more required `'\0'` terminators. 5. Observe an ASAN invalid read or responder termination/restart behavior, depending on build and runtime conditions. Mitigation: Restrict local access to the PAM responder UNIX socket to trusted users where operationally possible. If protocol v1 requests can be avoided in the affected environment, that reduces exposure, but there is no complete mitigation short of patching the v1 parser to reject zero-length and truncated inputs before any out-of-bounds dereference occurs. Proposed Fix: Reject zero-length bodies before evaluating `blen - 1`, and check `end >= blen` before each `body[end]` dereference while parsing the v1 NUL-terminated fields. ```diff diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c index 0000000..1111111 100644 — a/src/responder/pam/pamsrv_cmd.c +++ b/src/responder/pam/pamsrv_cmd.c @@ -475,6 +475,11 @@ static int pam_parse_in_data(struct pam_data *pd, size_t last; int ret; + /* Prevent size_t underflow and invalid first dereference */ + if (blen == 0) { + return EINVAL; + } + last = blen - 1; end = 0; @@ -482,27 +487,42 @@ static int pam_parse_in_data(struct pam_data *pd, /* user name */ for (start = end; end < last; end++) if (body[end] == '\0') break; if (body[end++] != '\0') return EINVAL; + if (end >= blen || body[end] != '\0') return EINVAL; + end++; pd->logon_name = (char *) &body[start]; for (start = end; end < last; end++) if (body[end] == '\0') break; if (body[end++] != '\0') return EINVAL; + if (end >= blen || body[end] != '\0') return EINVAL; + end++; pd->service = (char *) &body[start]; for (start = end; end < last; end++) if (body[end] == '\0') break; if (body[end++] != '\0') return EINVAL; + if (end >= blen || body[end] != '\0') return EINVAL; + end++; pd->tty = (char *) &body[start]; for (start = end; end < last; end++) if (body[end] == '\0') break; if (body[end++] != '\0') return EINVAL; + if (end >= blen || body[end] != '\0') return EINVAL; + end++; pd->ruser = (char *) &body[start]; for (start = end; end < last; end++) if (body[end] == '\0') break; if (body[end++] != '\0') return EINVAL; + if (end >= blen || body[end] != '\0') return EINVAL; + end++; pd->rhost = (char *) &body[start]; ``` ------ This report was generated using AI technology. Always review AI-generated content prior to use