Bug 2478512 (CVE-2026-85231) - CVE-2026-85231 libtirpc: libtirpc: Denial of service via unbounded memory allocation during RPCSEC_GSS decoding
Summary: CVE-2026-85231 libtirpc: libtirpc: Denial of service via unbounded memory all...
Keywords:
Status: NEW
Alias: CVE-2026-85231
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Product Security DevOps Team
QA Contact:
URL:
Whiteboard:
Depends On: 2554148
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-05-18 03:37 UTC by OSIDB Bzimport
Modified: 2026-10-16 15:16 UTC (History)
18 users (show)

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


Attachments (Terms of Use)

Description OSIDB Bzimport 2026-05-18 03:37:10 UTC
AI_ONLY_REPORT
package: libtirpc-1.3.7-2.1.hum1
------
Summary: Unbounded memory allocation during RPCSEC_GSS unwrap due to  
(u_int)-1 maxsize: authenticated remote denial of service by forcing  
oversized pre-verification allocations in RPCSEC_GSS unwrap handling
Requirements to exploit: The attacker must reach an RPC service linked  
against `libtirpc-1.3.7-2.1.hum1`, built with RPCSEC_GSS support,  
configured to use `RPCSEC_GSS_SVC_INTEGRITY` or `RPCSEC_GSS_SVC_PRIVACY`,  
establish a valid RPCSEC_GSS context, and send oversized wrapped  
`RPCSEC_GSS_DATA` requests that the transport will accept.
Component affected: `libtirpc`, `src/authgss_prot.c`  
(`xdr_rpc_gss_unwrap_data()`, `xdr_rpc_gss_buf()`), with attacker-driven  
allocation occurring in `src/xdr.c` (`xdr_bytes()`)
Version affected: `libtirpc-1.3.7-2.1.hum1` when built with RPCSEC_GSS  
support and used by an RPC service that accepts `RPCSEC_GSS_SVC_INTEGRITY`  
or `RPCSEC_GSS_SVC_PRIVACY` traffic
Patch available: no released package fix established; proposed patch  
included below
Version fixed: unknown
Upstream coordination: Notified privately.
CVSS: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H - 6.5 (MEDIUM)
AV:N - The attack is carried out over the network against a reachable  
RPC service.
AC:L - Once a valid RPCSEC_GSS context exists, the attacker only needs  
to send oversized wrapped blobs with attacker-chosen length fields.
PR:L - A valid RPCSEC_GSS context is required; the issue is not  
reachable as an anonymous network attack.
UI:N - No user interaction is required.
S:U - The impact is confined to the vulnerable service process.
C:N - No confidentiality impact is demonstrated by the available  
evidence.
I:N - No integrity impact is demonstrated by the available evidence.
A:H - Repeated oversized allocations can exhaust memory and destabilize  
or terminate the service.
Impact: Moderate. The established impact is denial of service in a  
network-facing path, but exploitation is conditional on RPCSEC_GSS being  
enabled in integrity or privacy mode, the attacker first establishing a  
valid RPCSEC_GSS context, and the deployment allowing sufficiently large  
wrapped requests to reach the decode path. This is a real availability  
issue, but the configuration and authentication preconditions make it less  
straightforward than the remote DoS cases typically rated Important.
Embargo: no
Reason: The available evidence supports an authenticated,  
configuration-dependent denial of service only. No code execution,  
confidentiality impact, or integrity impact is demonstrated, so normal  
coordinated remediation appears proportionate.
Acknowledgement: Aisle Research
Vulnerability Details: In `xdr_rpc_gss_unwrap_data()`, the integrity and  
privacy paths decode attacker-controlled wrapped buffers using  
`xdr_rpc_gss_buf(..., (u_int)-1)`. `xdr_rpc_gss_buf()` forwards that value  
to `xdr_bytes()`. During `XDR_DECODE`, `xdr_bytes()` reads the incoming  
length and allocates `mem_alloc(nodesize)` when the destination pointer is  
`NULL`. Because `maxsize` is effectively unbounded in this path, allocation  
can occur before `gss_verify_mic()` or `gss_unwrap()` rejects the wrapped  
message.
Focused excerpts from `src/authgss_prot.c`:
```c
if (!xdr_rpc_gss_buf(xdrs, &databuf, (u_int)-1)) {
LIBTIRPC_DEBUG(1, ("xdr_rpc_gss_unwrap_data: decode databody_integ  
failed"));
return (FALSE);
}
if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, (u_int)-1)) {
gss_release_buffer(&min_stat, &databuf);
LIBTIRPC_DEBUG(1, ("xdr_rpc_gss_unwrap_data: decode checksum failed"));
return (FALSE);
}
...
if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, (u_int)-1)) {
LIBTIRPC_DEBUG(1, ("xdr_rpc_gss_unwrap_data: decode databody_priv  
failed"));
return (FALSE);
}
```
Focused excerpts from `src/xdr.c`:
```c
if (! xdr_u_int(xdrs, sizep)) {
return (FALSE);
}
nodesize = *sizep;
if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
return (FALSE);
}
...
if (sp == NULL) {
*cpp = sp = mem_alloc(nodesize);
allocated = TRUE;
}
```
The available evidence supports a denial-of-service outcome through memory  
pressure or process termination under pressure. The exact amount allocable  
per request still depends on transport delivery, deployment-specific  
limits, and concurrency, and this report does not assert confidentiality or  
integrity impact. This report also only asserts the issue in the reviewed  
SRPM package.
Steps to reproduce:
1. Build or deploy an RPC service linked against `libtirpc-1.3.7-2.1.hum1`  
with RPCSEC_GSS support enabled and configured to use  
`RPCSEC_GSS_SVC_INTEGRITY` or `RPCSEC_GSS_SVC_PRIVACY`.
2. Establish a valid RPCSEC_GSS security context against the service.
3. Send `RPCSEC_GSS_DATA` requests whose wrapped body length fields are  
very large but still deliverable over the transport in use.
4. Observe memory allocation in `xdr_bytes()` during  
`xdr_rpc_gss_unwrap_data()` before `gss_verify_mic()` or `gss_unwrap()`  
completes verification.
5. Repeat the request or send several such requests concurrently to drive  
RSS growth, memory pressure, service degradation, or process termination.
Mitigation: Until a fix is available, reduce exposure by disabling  
RPCSEC_GSS integrity/privacy on externally reachable services where  
feasible, enforcing strict request or transport record size limits in the  
embedding RPC service before wrapped blob decode, and using process memory  
limits or supervision to contain single-process exhaustion.
Proposed Fix: A minimal mitigation is to replace the `(u_int)-1` decode  
bound with a fixed upper limit so oversized wrapped blobs are rejected  
before allocation. A stronger follow-up would derive the limit from  
negotiated context or transport limits, such as  
`rpc_gss_svc_max_data_length()`, instead of using a constant cap.
```diff
diff --git a/src/authgss_prot.c b/src/authgss_prot.c
— a/src/authgss_prot.c
+++ b/src/authgss_prot.c
@@ -50,6 +50,9 @@
/* additional space needed for encoding */
#define RPC_SLACK_SPACE 1024
+/* hard upper bound to prevent pre-verification memory exhaustion */
+#define RPCSEC_GSS_MAX_UNWRAP (16U * 1024U * 1024U)
+
bool_t
xdr_rpc_gss_unwrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr,
gss_ctx_id_t ctx, gss_qop_t qop,
@@ -227,12 +230,12 @@ xdr_rpc_gss_unwrap_data(...)
if (svc == RPCSEC_GSS_SVC_INTEGRITY) {
/* Decode databody_integ. */
       if (!xdr_rpc_gss_buf(xdrs, &databuf, (u_int)-1)) {
+        if (!xdr_rpc_gss_buf(xdrs, &databuf, RPCSEC_GSS_MAX_UNWRAP)) {
              return (FALSE);
          }
          /* Decode checksum. */

       if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, (u_int)-1)) {
+        if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, RPCSEC_GSS_MAX_UNWRAP)) {
              gss_release_buffer(&min_stat, &databuf);
              return (FALSE);
          }
@@ -251,7 +254,7 @@ xdr_rpc_gss_unwrap_data(...)
      }
      else if (svc == RPCSEC_GSS_SVC_PRIVACY) {
          /* Decode databody_priv. */

       if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, (u_int)-1)) {
+        if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, RPCSEC_GSS_MAX_UNWRAP)) {
              return (FALSE);
          }
```


------
This report was generated using AI technology. Always review AI-generated  
content prior to use


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