Bug 2539561 - CVE-2026-90996 sssd: sssd: Denial of Service in NSS responder via crafted zero-length requests [fedora-all]
Summary: CVE-2026-90996 sssd: sssd: Denial of Service in NSS responder via crafted zer...
Keywords:
Status: ON_QA
Alias: None
Product: Fedora
Classification: Fedora
Component: sssd
Version: rawhide
Hardware: Unspecified
OS: Unspecified
medium
medium
Target Milestone: ---
Assignee: Alexey Tikhonov
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard: {"flaws": ["2e6bd2ae-3aa5-4f89-acb8-a...
: 2539558 (view as bug list)
Depends On:
Blocks: CVE-2026-90996
TreeView+ depends on / blocked
 
Reported: 2026-09-23 17:17 UTC by Marco Benatto
Modified: 2026-10-08 13:42 UTC (History)
7 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Type: ---
Embargoed:


Attachments (Terms of Use)

Description Marco Benatto 2026-09-23 17:17:34 UTC
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: Local DoS Risk in NSS Responder Due to Zero-Length Request Body  
Underflow: crafted header-only NSS requests can force `blen == 0` in  
parsers that inspect `body[blen - 1]`, and if the final header byte is  
`'\0'` the path can continue into `sss_utf8_check(body, SIZE_MAX)`,  
creating a local denial-of-service condition in the NSS responder.
Requirements to exploit: Ability to run code as a local unprivileged user  
on a system where the NSS responder is enabled and reachable through its  
UNIX socket, and to send a crafted 16-byte request to an affected parser  
such as `SSS_NSS_GETPWNAM`.
Component affected: `sssd-2.12.0-1.el10`; NSS responder request parsing in  
`src/responder/nss/nss_protocol.c` (`sss_nss_protocol_parse_name`,  
`sss_nss_protocol_parse_svc_name`, `sss_nss_protocol_parse_svc_port`,  
`sss_nss_protocol_parse_cert`, and `sss_nss_protocol_parse_sid`)
Version affected: `sssd-2.12.0-1.el10` when the NSS responder is enabled  
and reachable through its local UNIX socket
Patch available: no released package fix established; proposed patch  
included below
Version fixed: unknown
Upstream coordination: Not yet established.
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 - Exploitation requires local access to the host and the NSS  
responder UNIX socket.
AC:L - A single crafted 16-byte header-only request is sufficient to  
reach the vulnerable parsing path.
PR:N - No prior privileges are required if the local user can connect to  
the responder socket.
UI:N - No user interaction is needed.
S:U - The impact is limited to the NSS responder within the same  
security scope.
C:N - No confidentiality impact was demonstrated.
I:N - No integrity impact was demonstrated.
A:L - The demonstrated outcome is local responder instability or  
termination; broader or reliably repeatable impact was not established from  
the available evidence.
Impact: Moderate. A local unprivileged user can affect availability of a  
system responder with a simple malformed request, which fits Red Hat's  
Moderate category for flaws that can still cause some availability  
compromise under constrained conditions. It does not fit Important or  
Critical because no remote attack path, privilege gain, confidentiality  
impact, or integrity impact was established.
Embargo: no
Reason: The issue is local-only, the demonstrated impact is limited to  
denial of service in the NSS responder, and the fix is a small validation  
change.
Acknowledgement: Aisle Research
Vulnerability Details: In `src/responder/nss/nss_protocol.c`, multiple NSS  
request parsers obtain the request body and immediately test `body[blen -  
1]` without first ensuring that `blen` is non-zero. The `SSS_NSS_GETPWNAM`  
path reaches `sss_nss_protocol_parse_name()`, and similar logic appears in  
`sss_nss_protocol_parse_svc_name()`, `sss_nss_protocol_parse_svc_port()`,  
`sss_nss_protocol_parse_cert()`, and `sss_nss_protocol_parse_sid()`.
```c
...
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;
}
/* If the body isn't valid UTF-8, fail */
if (!sss_utf8_check(body, blen - 1)) {
DEBUG(SSSDBG_CRIT_FAILURE, "Body is not UTF-8 string!\n");
return EINVAL;
}
...
```
`sss_packet_get_body()` derives the body length directly from the packet  
length:
```c
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;
}
```
A header-only request with `len == SSS_NSS_HEADER_SIZE` therefore yields  
`blen == 0`. In that case, the first `body[blen - 1]` access reads the last  
byte of the packet header rather than necessarily moving outside the packet  
allocation. However, if that header byte is `'\0'`,  
`sss_nss_protocol_parse_name()` continues into `sss_utf8_check(body, blen -  
1)` with `blen - 1 == SIZE_MAX`, creating an effectively unbounded UTF-8  
validation read. Based on the available evidence, that is sufficient for a  
realistic local denial of service against the NSS responder, while broader  
memory corruption or confidentiality/integrity impact was not established.
Steps to reproduce:
1. Ensure SSSD is running with the NSS responder enabled and identify the  
NSS socket, commonly `/var/lib/sss/pipes/nss`.
2. Connect to that UNIX socket as an unprivileged local user.
3. Send a 16-byte header-only request using a command that reaches  
`sss_nss_protocol_parse_name()`, such as `SSS_NSS_GETPWNAM (0x0011)`, with  
`len = 16`, `status = 0`, and `reserved = 0`.
4. Observe the responder under ASan, Valgrind, or equivalent crash  
monitoring. The parse path reaches `body[blen - 1]` with `blen == 0` and  
may continue into large-length UTF-8 validation.
5. Repeating the crafted request can destabilize or terminate the NSS  
responder process.
```python
import socket, struct
sock = "/var/lib/sss/pipes/nss"  # adjust if needed
hdr = struct.pack("<IIII", 16, 0x0011, 0, 0)  # len, cmd, status, reserved
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(sock)
s.sendall(hdr)
try:
print(s.recv(4096))
except Exception as e:
print("recv error:", e)
s.close()
```
Mitigation: The demonstrated attack path requires local access to the NSS  
responder UNIX socket. Environments that do not expose that socket to  
untrusted local users are not exposed to the demonstrated path. Where  
operationally acceptable, disabling the NSS responder until a fixed package  
is available removes the vulnerable surface.
Proposed Fix: Add an explicit `blen == 0` check before any `body[blen - 1]`  
access in the affected NSS parsers.
```diff
diff --git a/src/responder/nss/nss_protocol.c  
b/src/responder/nss/nss_protocol.c
index 0000000..0000000 100644
— a/src/responder/nss/nss_protocol.c
+++ b/src/responder/nss/nss_protocol.c
@@ -112,6 +112,11 @@ sss_nss_protocol_parse_name(struct cli_ctx *cli_ctx,  
const char **_rawname)
sss_packet_get_body(pctx->creq->in, &body, &blen);
+    if (blen == 0) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Body is empty!\n");
+        return EINVAL;
+    }
+
if (body[blen - 1] != '\0') {
DEBUG(SSSDBG_CRIT_FAILURE, "Body is not null terminated!\n");
return EINVAL;
@@ -270,6 +275,11 @@ sss_nss_protocol_parse_svc_name(struct cli_ctx  
*cli_ctx,
sss_packet_get_body(pctx->creq->in, &body, &blen);
+    if (blen == 0) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Body is empty!\n");
+        return EINVAL;
+    }
+
if (body[blen - 1] != '\0') {
DEBUG(SSSDBG_CRIT_FAILURE, "Body is not null terminated\n");
return EINVAL;
@@ -326,6 +336,11 @@ sss_nss_protocol_parse_svc_port(struct cli_ctx  
*cli_ctx,
sss_packet_get_body(pctx->creq->in, &body, &blen);
+    if (blen == 0) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Body is empty!\n");
+        return EINVAL;
+    }
+
if (body[blen - 1] != '\0') {
DEBUG(SSSDBG_CRIT_FAILURE, "Body is not null terminated\n");
return EINVAL;
@@ -372,6 +387,11 @@ sss_nss_protocol_parse_cert(struct cli_ctx *cli_ctx,
sss_packet_get_body(pctx->creq->in, &body, &blen);
+    if (blen == 0) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Body is empty!\n");
+        return EINVAL;
+    }
+
if (body[blen - 1] != '\0') {
DEBUG(SSSDBG_CRIT_FAILURE, "Body is not null terminated\n");
return EINVAL;
@@ -416,6 +436,11 @@ sss_nss_protocol_parse_sid(struct cli_ctx *cli_ctx,
sss_packet_get_body(pctx->creq->in, &body, &blen);
+    if (blen == 0) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Body is empty!\n");
+        return EINVAL;
+    }
+
if (body[blen - 1] != '\0') {
DEBUG(SSSDBG_CRIT_FAILURE, "Body is not null terminated\n");
return EINVAL;
```
------
This report was generated using AI technology. Always review AI-generated  
content prior to use

Comment 1 Marco Benatto 2026-09-23 17:35:01 UTC
*** Bug 2539558 has been marked as a duplicate of this bug. ***

Comment 2 Alexey Tikhonov 2026-09-25 09:57:53 UTC
Upstream PR: https://github.com/SSSD/sssd/pull/9330

Comment 3 Alexey Tikhonov 2026-09-30 16:26:28 UTC
(In reply to Alexey Tikhonov from comment #2)
> Upstream PR: https://github.com/SSSD/sssd/pull/9330

Fixed upstream: https://github.com/SSSD/sssd/commit/c7f1b8a3d506e38af3949eed19e034eb6a005bbf


Note You need to log in before you can comment on or make changes to this bug.