Bug 2569231 - CVE-2026-112319 krb5: MIT krb5 kadmind authenticated memory exhaustion DoS via unbounded RPC XDR allocation [fedora-all]
Summary: CVE-2026-112319 krb5: MIT krb5 kadmind authenticated memory exhaustion DoS vi...
Keywords:
Status: NEW
Alias: None
Product: Fedora
Classification: Fedora
Component: krb5
Version: rawhide
Hardware: Unspecified
OS: Unspecified
high
high
Target Milestone: ---
Assignee: Julien Rische
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard: {"flaws": ["4f2ec4dd-d387-47a2-b822-6...
Depends On:
Blocks: CVE-2026-112319
TreeView+ depends on / blocked
 
Reported: 2026-11-09 18:17 UTC by Samuele Negrini
Modified: 2026-11-09 18:17 UTC (History)
7 users (show)

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


Attachments (Terms of Use)

Description Samuele Negrini 2026-11-09 18:17:59 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: krb5-1.21.3-8.el10_0
------
Summary: Authenticated Memory Exhaustion and Leak in RPCSEC_GSS Unwrapping  
(`xdr_rpc_gss_unwrap_data`): authenticated RPCSEC_GSS DATA requests can  
supply oversized XDR lengths that trigger large pre-verification  
allocations and leave some decode-failure allocations unreleased, enabling  
repeatable memory exhaustion and denial of service.
Requirements to exploit: A remote attacker needs network reachability to a  
deployed service using this SRPM's GSSRPC unwrap path, a valid RPCSEC_GSS  
security context accepted by that service, and the ability to send  
oversized or truncated wrapped RPC arguments.
Component affected: `krb5` library code in  
`src/lib/rpc/authgss_prot.c:xdr_rpc_gss_unwrap_data` via `xdr_rpc_gss_buf`,  
with the allocation behavior in `src/lib/rpc/xdr.c:xdr_bytes`
Version affected: `krb5-1.21.3-8.el10_0` when deployed with a service that  
accepts authenticated `RPCSEC_GSS_DATA` requests through the GSSRPC unwrap  
path
Patch available: no released package fix established; proposed patch  
included below
Version fixed: unknown
Upstream coordination: Not notified.
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 issue is reachable over the network against a service  
exposing the RPCSEC_GSS unwrap path.
AC:L - Once authenticated, the attack is straightforward: send oversized  
XDR lengths and a malformed or incomplete wrapped body.
PR:L - A valid RPCSEC_GSS context is required.
UI:N - No user interaction is needed.
S:U - The impact is confined to the targeted service process.
C:N - No confidentiality impact is established by the available evidence.
I:N - No integrity impact is established by the available evidence.
A:H - Large allocations plus unreleased buffers on some decode failures  
can exhaust memory and deny service.
Impact: Important. Where this RPCSEC_GSS path is exposed, an authenticated  
remote client can directly compromise availability by forcing repeated  
high-memory allocations and leak-driven growth in the service process. This  
aligns with Red Hat's Important category for remote denial of service; the  
authentication requirement and lack of demonstrated confidentiality or  
integrity impact keep it below Critical.
Embargo: no
Reason: The issue requires valid RPCSEC_GSS credentials and exposure of  
a vulnerable RPCSEC_GSS service, and the demonstrated impact is denial of  
service rather than code execution or privilege escalation.
Acknowledgement: Aisle Research
Vulnerability Details: `xdr_rpc_gss_unwrap_data` decodes  
attacker-controlled wrapped buffers with `maxsize = (unsigned int)-1` for  
both integrity and privacy services. That value is then passed into  
`xdr_bytes`, which allocates memory directly from the wire length before  
MIC verification or unwrap validation completes.
```c
if (svc == RPCSEC_GSS_SVC_INTEGRITY) {
/* Decode databody_integ. */
if (!xdr_rpc_gss_buf(xdrs, &databuf, (unsigned int)-1)) {
log_debug("xdr decode databody_integ failed");
return (FALSE);
}
/* Decode checksum. */
if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, (unsigned int)-1)) {
gss_release_buffer(&min_stat, &databuf);
log_debug("xdr decode checksum failed");
return (FALSE);
}
/* Verify checksum and QOP. */
maj_stat = gss_verify_mic(&min_stat, ctx, &databuf,
&wrapbuf, &qop_state);
free(wrapbuf.value);
if (maj_stat != GSS_S_COMPLETE || qop_state != qop) {
gss_release_buffer(&min_stat, &databuf);
log_status("gss_verify_mic", maj_stat, min_stat);
return (FALSE);
}
}
else if (svc == RPCSEC_GSS_SVC_PRIVACY) {
/* Decode databody_priv. */
if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, (unsigned int)-1)) {
log_debug("xdr decode databody_priv failed");
return (FALSE);
}
```
```c
if (! xdr_u_int(xdrs, sizep)) {
return (FALSE);
}
nodesize = *sizep;
if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
return (FALSE);
}
/*
now deal with the actual bytes
	 */
	switch (xdrs->x_op) {


case XDR_DECODE:
if (nodesize == 0) {
return (TRUE);
}
if (sp == NULL) {
*cpp = sp = (char *)mem_alloc(nodesize);
}
```
Because `maxsize` is effectively `UINT_MAX` in this call path, the  
`nodesize > maxsize` check does not provide a practical bound. The  
allocation happens before `gss_verify_mic()` or `gss_unwrap()`, and some  
decode-error exits return `FALSE` without releasing every buffer that may  
already have been allocated. Repeated malformed or incomplete authenticated  
requests can therefore grow process RSS over time and deny service. The  
available evidence supports an availability issue; no direct  
confidentiality or integrity impact was established.
Steps to reproduce:
1. Start a service using this GSSRPC code path with RPCSEC_GSS enabled over  
TCP, for example an administration service using the GSSRPC server path.
2. Establish a valid RPCSEC_GSS context as an authenticated client.
3. Send an `RPCSEC_GSS_DATA` request with `gc_proc = RPCSEC_GSS_DATA` and  
`gc_svc = RPCSEC_GSS_SVC_INTEGRITY` or `RPCSEC_GSS_SVC_PRIVACY`.
4. Set the wrapped `databuf` or `wrapbuf` XDR length prefix to a large  
value, such as `64 MB` or larger.
5. Trigger decode failure after allocation by sending a malformed or  
incomplete wrapped body and closing the connection, then repeat the request.
6. Observe process RSS increasing over time, followed by service  
degradation or denial of service.
Mitigation: Until a code fix is available, restrict network exposure of  
services that use this RPCSEC_GSS unwrap path to trusted authenticated  
principals and apply conservative service memory limits where possible.  
Existing connection-count controls can reduce concurrent amplification, but  
they do not prevent serial memory growth because allocation occurs before  
MIC or unwrap verification.
Proposed Fix: A minimal patch is below. It introduces a bounded unwrap size  
and adds cleanup in decode-failure branches that can leave `wrapbuf`  
allocated. The bound can also be made configurable or tied to transport  
policy.
```diff
diff --git a/src/lib/rpc/authgss_prot.c b/src/lib/rpc/authgss_prot.c
— a/src/lib/rpc/authgss_prot.c
+++ b/src/lib/rpc/authgss_prot.c
@@ -46,6 +46,9 @@
#include <gssapi/gssapi.h>
#endif
+/* Upper bound for decoded wrapped RPCSEC_GSS payloads. */
+#define RPCSEC_GSS_MAX_UNWRAP (16U * 1024U * 1024U)
+
bool_t
xdr_rpc_gss_buf(XDR *xdrs, gss_buffer_t buf, u_int maxsize)
{
@@ -202,13 +205,18 @@ xdr_rpc_gss_unwrap_data(XDR *xdrs, xdrproc_t  
xdr_func, caddr_t xdr_ptr,
if (svc == RPCSEC_GSS_SVC_INTEGRITY) {
/* Decode databody_integ. */
-		if (!xdr_rpc_gss_buf(xdrs, &databuf, (unsigned int)-1)) {
+		if (!xdr_rpc_gss_buf(xdrs, &databuf, RPCSEC_GSS_MAX_UNWRAP)) {
log_debug("xdr decode databody_integ failed");
return (FALSE);
}
/* Decode checksum. */
-		if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, (unsigned int)-1)) {
+		if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, RPCSEC_GSS_MAX_UNWRAP)) {
gss_release_buffer(&min_stat, &databuf);
+			if (wrapbuf.value != NULL)
+				free(wrapbuf.value);
log_debug("xdr decode checksum failed");
return (FALSE);
}
@@ -225,7 +233,10 @@ xdr_rpc_gss_unwrap_data(XDR *xdrs, xdrproc_t xdr_func,  
caddr_t xdr_ptr,
}
else if (svc == RPCSEC_GSS_SVC_PRIVACY) {
/* Decode databody_priv. */
-		if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, (unsigned int)-1)) {
+		if (!xdr_rpc_gss_buf(xdrs, &wrapbuf, RPCSEC_GSS_MAX_UNWRAP)) {
+			if (wrapbuf.value != NULL)
+				free(wrapbuf.value);
log_debug("xdr decode databody_priv failed");
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.