Fedora Account System
Red Hat Associate
Red Hat Customer
Disclaimer: Community trackers are created by Red Hat Product Security team on a best effort basis. Package maintainers are required to ascertain if the flaw indeed affects their package, before starting the update process. AI_ONLY_REPORT package: sssd-2.12.0-1.el10 ------ Summary: NSS responder length underflow in packet parsing (`sss_packet_get_body`) enables local OOB read / crash: undersized client-controlled packet lengths can underflow the computed body length and drive an out-of-bounds read in NSS request parsing, likely crashing the responder. Requirements to exploit: An attacker needs the ability to run a local process on a system running the NSS responder and to connect to its UNIX socket and send a request with `len < 16`. In the reviewed tree, NSS is initialized with `SCKT_RSP_UMASK`, and the peer-UID gate is only applied when `allowed_uids` is configured; deployment-specific socket ACLs or socket-activation settings may still reduce which local users can reach the socket. Component affected: `sssd-2.12.0-1.el10`, NSS responder packet parsing in `src/responder/common/responder_packet.c` (`sss_packet_recv()`, `sss_packet_get_body()`) and `src/responder/nss/nss_protocol.c` (`sss_nss_protocol_parse_name()`) 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 the NSS responder UNIX socket. AC:L - The trigger is a short packet header with a client-controlled `len` smaller than the 16-byte protocol header; no race or uncommon precondition is established. PR:N - Where the NSS socket is reachable, the reviewed tree does not require responder-specific privileges before sending the malformed request; deployment-specific ACLs can reduce reachability. UI:N - No user interaction is required. S:U - The impact stays within the SSSD responder's security scope. C:N - The available materials show an out-of-bounds read but do not demonstrate practical data disclosure. I:N - No integrity impact is demonstrated. A:H - The established effect is a likely responder crash or denial of service in the NSS path. Impact: Moderate. The available evidence supports a low-complexity local denial of service against the NSS responder, not remote compromise, privilege escalation, or a demonstrated confidentiality breach. Under Red Hat's guidance this is more than Low because it can disrupt availability of NSS account lookup functionality on exposed systems, but it is below Important because the currently supported impact is local and availability-focused. Embargo: no Reason: The demonstrated impact is a local responder crash / denial of service with straightforward remediation and practical exposure reduction through local socket access controls. Acknowledgement: Aisle Research Vulnerability Details: The directly observed path is request receipt in `sss_packet_recv()` followed by NSS request parsing in `sss_nss_protocol_parse_name()`. `sss_packet_recv()` accepts a packet once `packet->iop >= new_len`, but there is no lower-bound check that `new_len >= SSS_NSS_HEADER_SIZE`. `sss_packet_get_body()` then subtracts `SSS_NSS_HEADER_SIZE` unconditionally, and the NSS name parser dereferences `body[blen - 1]` before any length check. With a crafted header such as `len=8`, `blen` underflows as `size_t` and the null-termination test becomes an out-of-bounds read. ```c int sss_packet_recv(struct sss_packet *packet, int fd) { ... packet->iop += rb; if (packet->iop < SSS_PACKET_CMD_OFFSET) { return EAGAIN; } new_len = sss_packet_get_len(packet); if (new_len > packet->memsize) { enum sss_cli_command cmd = sss_packet_get_cmd(packet); size_t max_recv_size; ... } if (packet->iop < new_len) { return EAGAIN; } return EOK; } void sss_packet_get_body(struct sss_packet *packet, uint8_t **body, size_t *blen) { *body = packet->buffer + SSS_PACKET_BODY_OFFSET; *blen = sss_packet_get_len(packet) - SSS_NSS_HEADER_SIZE; } errno_t sss_nss_protocol_parse_name(struct cli_ctx *cli_ctx, const char **_rawname) { ... sss_packet_get_body(pctx->creq->in, &body, &blen); /* If not terminated fail. */ if (body[blen - 1] != '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Body is not null terminated!\n"); return EINVAL; } ... } ``` The likely consequence is responder termination or request failure in the NSS path. The available materials do not establish a reliable confidentiality disclosure, integrity impact, or code execution primitive. The behavior is confirmed in the reviewed `sssd-2.12.0` source tree; the available materials do not establish a narrower introduction point or a released fix. Steps to reproduce: 1. Run a system with SSSD active and the NSS responder enabled. 2. As a local user that can reach the NSS responder UNIX socket, connect to the runtime NSS socket path. A common path is `/var/lib/sss/pipes/nss`. 3. Send an 8-byte request header with `len=8` and `cmd=SSS_NSS_GETPWNAM (0x0011)`: ```python import socket, struct s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) s.connect("/var/lib/sss/pipes/nss") s.sendall(struct.pack("<II", 8, 0x0011)) ``` 4. Observe that the responder may close the connection unexpectedly or crash. Under ASAN or Valgrind, the invalid read is expected in the NSS parse path around the `body[blen - 1]` check. Mitigation: Until a fixed package is available, restrict access to the NSS responder UNIX socket to trusted local users where operationally possible. Where deployment configuration supports it, apply peer-UID restrictions such as `allowed_uids` or equivalent socket ACLs. This reduces reachability but does not correct the parser flaw. Proposed Fix: Add a minimum-length guard in `sss_packet_recv()` before the packet is accepted as complete. ```diff diff --git a/src/responder/common/responder_packet.c b/src/responder/common/responder_packet.c index 0000000..0000000 100644 — a/src/responder/common/responder_packet.c +++ b/src/responder/common/responder_packet.c @@ -217,6 +217,12 @@ int sss_packet_recv(struct sss_packet *packet, int fd) new_len = sss_packet_get_len(packet); + if (new_len < SSS_NSS_HEADER_SIZE) { + DEBUG(SSSDBG_OP_FAILURE, + "Refusing undersized packet from fd %d (length %zu bytes)\n", + fd, new_len); + return EINVAL; + } + if (new_len > packet->memsize) { enum sss_cli_command cmd = sss_packet_get_cmd(packet); size_t max_recv_size; ``` ------ This report was generated using AI technology. Always review AI-generated content prior to use
*** Bug 2546257 has been marked as a duplicate of this bug. ***
Upstream PR: https://github.com/SSSD/sssd/pull/9463