Fedora Account System
Red Hat Associate
Red Hat Customer
AI_ONLY_REPORT package: sssd-2.12.0-1.el10 ------ Summary: Out-of-Bounds Write in SSSD NFS idmap Plugin (`sss_nfs_client.c`) on memcache hit: destination buffer length is checked and `ENOBUFS` is set, but `memcpy()` still copies the full cached user or group name into an undersized caller buffer. Requirements to exploit: The NFS idmap plugin from this SRPM must be in use, `rpc.idmapd` must be configured with `Method = sss`, and the memcache path must be enabled (`memcache = true`, the documented default for the plugin). Exploitation then requires a `uid_to_name` or `gid_to_name` lookup that hits memcache and returns a cached `pw_name` or `gr_name` longer than the caller-supplied `len`. The available source does not establish the caller's buffer-sizing policy, so real-world exploitability depends on external caller and deployment behavior. Component affected: `sssd-2.12.0-1.el10`, NFS `libnfsidmap` plugin implementation in `src/sss_client/nfs/sss_nfs_client.c`, specifically `get_user_from_mc()` and `get_group_from_mc()`, reachable from `sss_nfs_uid_to_name()` and `sss_nfs_gid_to_name()`. Version affected: `sssd-2.12.0-1.el10`; reachable when the NFS idmap plugin is built and `rpc.idmapd` uses `Method = sss` with `memcache = true` 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:H/PR:L/UI:N/S:U/C:L/I:L/A:H - 6.1 (MEDIUM) AV:L - The issue is established in local plugin usage on a system running the SSSD NFS idmap path; remote exploitability is not demonstrated by the available evidence. AC:H - Triggering requires a specific buffer-length mismatch in an external caller while the memcache path is enabled and hit by lookup traffic. PR:L - A successful attack typically assumes at least an authenticated foothold or equivalent ability to influence relevant identity data and trigger lookups on the affected host. UI:N - No separate user interaction is required once the vulnerable lookup path is reachable. S:U - The memory corruption occurs within the security scope of the idmap process using this plugin. C:L - Limited disclosure from process memory cannot be ruled out once corruption occurs, but broader disclosure is not established. I:L - The out-of-bounds write can alter adjacent process memory, although reliable controlled modification is not shown. A:H - Memory corruption in the lookup path can crash or destabilize the idmap process handling these requests. Impact: Moderate. This is a real out-of-bounds write, but it does not fit Red Hat's Important or Critical categories on the available evidence because easy remote exploitation and reliable system compromise are not established. Exploitability depends on a specific build and runtime configuration, use of the SSSD NFS idmap plugin, the memcache-backed lookup path, and a caller-supplied buffer that is shorter than the cached name. That aligns more closely with Red Hat's Moderate rating for flaws that can affect confidentiality, integrity, or availability under certain circumstances or in less common configurations. The current evidence does not support claiming reliable privilege escalation or code execution from this flaw alone. Embargo: no Reason: The issue appears to be Moderate and configuration-dependent, and there is a straightforward mitigation by disabling the vulnerable memcache path until a fix is available. Acknowledgement: Aisle Research Vulnerability Details: In both `get_user_from_mc()` and `get_group_from_mc()`, the code detects that the cached reply is larger than the destination buffer and sets `rc = ENOBUFS`, but it does not stop before copying. As a result, a memcache hit with `pw_name_len > len` or `gr_name_len > len` still executes `memcpy()` and writes past the end of the caller buffer. ```c pw_name_len = strlen(pwd.pw_name) + 1; if (pw_name_len > len) { IDMAP_LOG(0, ("%s: reply too long; pw_name_len=%lu, len=%lu", _func_, pw_name_len, len)); rc = ENOBUFS; } memcpy(name, pwd.pw_name, pw_name_len); ``` ```c gr_name_len = strlen(grp.gr_name) + 1; if (gr_name_len > len) { IDMAP_LOG(0, ("%s: reply too long; gr_name_len=%lu, len=%lu", _func_, gr_name_len, len)); rc = ENOBUFS; } memcpy(name, grp.gr_name, gr_name_len); ``` The affected code is at `src/sss_client/nfs/sss_nfs_client.c:179-185` and `src/sss_client/nfs/sss_nfs_client.c:220-226`. The trigger path is `sss_nfs_uid_to_name()` -> `get_user_from_mc()` and `sss_nfs_gid_to_name()` -> `get_group_from_mc()`. The unsafe write inside the plugin is direct and unconditional once an oversized memcache result is returned. The exact sizing policy for `len` is external to these functions, so practical exploitability depends on caller behavior. Steps to reproduce: 1. Build with ASan (`-fsanitize=address`) and include the NFS idmap plugin (`BUILD_NFS_IDMAP` path). 2. Configure `rpc.idmapd` to use the SSSD plugin (`Method = sss`) and keep `memcache = true` (default in `sss_rpcidmapd.5.xml`). 3. Ensure memcache has a user or group name longer than the destination buffer supplied by the caller. 4. Trigger `uid_to_name` or `gid_to_name` resolution so the memcache path is used. 5. At the `memcpy()` sites above, verify `pw_name_len > len` or `gr_name_len > len` and observe the out-of-bounds write or ASan report. Mitigation: If an immediate fix is not available, set `memcache = false` for the SSSD `rpc.idmapd` plugin so lookups avoid `get_user_from_mc()` and `get_group_from_mc()`, which are the vulnerable paths. If that is not acceptable, avoid using `Method = sss` for `rpc.idmapd` until a fixed build is available. Proposed Fix: Abort the memcache-hit path before `memcpy()` when the returned name does not fit in the caller buffer. ```diff diff --git a/src/sss_client/nfs/sss_nfs_client.c b/src/sss_client/nfs/sss_nfs_client.c @@ -179,10 +179,11 @@ static int get_user_from_mc(char *name, size_t len, uid_t uid) if (pw_name_len > len) { IDMAP_LOG(0, ("%s: reply too long; pw_name_len=%lu, len=%lu", _func_, pw_name_len, len)); rc = ENOBUFS; + goto done; } IDMAP_LOG(1, ("found uid %i in memcache", uid)); memcpy(name, pwd.pw_name, pw_name_len); @@ -220,10 +221,11 @@ static int get_group_from_mc(char *name, size_t len, id_t gid) if (gr_name_len > len) { IDMAP_LOG(0, ("%s: reply too long; gr_name_len=%lu, len=%lu", _func_, gr_name_len, len)); rc = ENOBUFS; + goto done; } IDMAP_LOG(1, ("found gid %i in memcache", gid)); memcpy(name, grp.gr_name, gr_name_len); ``` ------ This report was generated using AI technology. Always review AI-generated content prior to use