Where
-Infinity
0
Severity
7.5
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: Unauthenticated Memory-Exhaustion DoS in kadmind legacy AUTHGSSAPI handshake (svcauthgssapi.c): repeated unauthenticated AUTHGSSAPIINIT failures can allocate per-client state that is retained until timeout-based cleanup, allowing remote memory-pressure denial of service. Requirements to exploit: Network reachability to a kadmind admin RPC endpoint and the ability to send crafted unauthenticated AUTHGSSAPIINIT requests that reach the legacy server-side AUTHGSSAPI handler; no valid Kerberos credentials or user interaction are required. Component affected: krb5-1.21.3-8.el100, src/lib/rpc/svcauthgssapi.c, gssrpcsvcauthgssapi() legacy AUTHGSSAPI handshake path reachable via kadmind Version affected: krb5-1.21.3-8.el100 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:N/UI:N/S:U/C:N/I:N/A:H - 7.5 (HIGH) AV:N - The attack is delivered over the network to a reachable kadmind RPC service. AC:L - Repeated malformed AUTHGSSAPIINIT traffic is sufficient; no race or unusual precondition is established. PR:N - No Kerberos credentials or other prior authentication are required. UI:N - No user interaction is needed. S:U - The impact stays within the authority of the vulnerable service. C:N - No confidentiality impact is established from the available evidence. I:N - No integrity impact is established from the available evidence. A:H - Repeated retained allocations can drive sustained memory growth and deny service. Impact: Important. Red Hat classifies flaws that allow remote users to cause a denial of service as Important when they can compromise availability of resources. Here, the established effect is unauthenticated remote memory exhaustion against a reachable kadmind service. Critical is not supported because the evidence does not show arbitrary code execution or broader system compromise, and the demonstrated impact is availability-only. Embargo: no Reason: The established impact is denial of service on an administrative service, and exposure can be materially reduced by restricting network access to kadmind while a fix is prepared. Private coordination is still useful, but the currently established impact does not strongly support an extended embargo. Acknowledgement: Aisle Research Vulnerability Details: In gssrpcsvcauthgssapi(), an AUTHGSSAPIINIT request with an empty client handle creates new per-client state before context establishment. That state is inserted into the global clients list and given a 15-minute initiation timeout. When context establishment fails, the function sends an error response and returns through error: without destroying the just-created entry. c if (creds.authmsg && rqst->rqproc == AUTHGSSAPIINIT) { ... clientdata = createclient(); ... } c clientdata->expiration = time(0) + INITIATIONTIMEOUT; / 6015 / c if (callres.gssmajor != GSSSCOMPLETE && callres.gssmajor != GSSSCONTINUENEEDED) { ... svcsendreply(...); nodispatch = TRUE; ret = AUTHOK; goto error; / no destroyclient(clientdata) / } Repeated unauthenticated failures therefore accumulate retained svcauthgssapidata entries until timeout-based cleanup runs. The same cleanup gap also affects other post-allocation INIT failure paths that return through error: after createclient() has already succeeded, including malformed init arguments or unsupported INIT versions. Based on the available evidence, the established impact is denial of service through attacker-driven memory growth; no confidentiality or integrity impact is established. Steps to reproduce: 1. Run kadmind from this package and ensure the admin RPC service is reachable, typically on 749/tcp. 2. Open one TCP connection to the service. 3. Repeatedly send RPC calls with credential flavor AUTHGSSAPI, procedure AUTHGSSAPIINIT, authmsg = TRUE, an empty clienthandle, and an invalid or malformed init token. Malformed INIT arguments after credential parsing also exercise post-allocation failure handling. 4. Observe that failed INIT requests return an error response while also yielding a fresh clienthandle, indicating that new server-side client state was created. 5. Continue sending failures at a moderate rate and monitor kadmind memory usage. Memory rises and remains elevated until the initiation timeout expires (about 15 minutes), demonstrating unauthenticated memory-pressure denial of service. Mitigation: Restrict network access to the kadmind admin RPC service to trusted management hosts, and apply network filtering or rate limiting for repeated failed AUTHGSSAPIINIT traffic where possible. Until a fix is available, avoid exposing this administrative interface to untrusted networks and monitor kadmind for abnormal memory growth. Proposed Fix: Track whether the current request created a new client entry and destroy that entry on all failure exits so partially initialized state is not left in the global client list. diff — a/src/lib/rpc/svcauthgssapi.c +++ b/src/lib/rpc/svcauthgssapi.c @@ -170,6 +170,7 @@ enum authstat gssrpcsvcauthgssapi( enum authstat ret; OMuint32 retflags; uint32t seqnum; + boolt createdclient = FALSE; @@ -248,6 +249,7 @@ enum authstat gssrpcsvcauthgssapi( if (clientdata == NULL) { ... } + createdclient = TRUE; } else { ... } @@ -461,6 +463,12 @@ enum authstat gssrpcsvcauthgssapi( gssreleasebuffer(&minorstat, &outputtoken); + if (createdclient) { + destroyclient(clientdata); + clientdata = NULL; + rqst->rqxprt->xpauth = &svcauthnone; + createdclient = FALSE; + } svcsendreply(rqst->rqxprt, (xdrproct)xdrauthgssapiinitres, (caddrt) &callres); nodispatch = TRUE; @@ -652,6 +660,12 @@ error: + if (createdclient && clientdata != NULL) { + destroyclient(clientdata); + clientdata = NULL; + rqst->rqxprt->xpauth = &svcauthnone; + createdclient = FALSE; + } if (creds.clienthandle.length != 0) { ... } ------ This report was generated using AI technology. Always review AI-generated content prior to use

1 / 3
Source: Red Hat
First published (updated )
Severity
7.5
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: Algorithmic complexity DoS in ASN.1 decodesequenceof() (unauthenticated KDC request parsing): repeated crafted AS-REQ or TGS-REQ messages can force one-by-one array growth while decoding PrincipalName.name-string, causing substantial CPU consumption in krb5kdc before authentication. Requirements to exploit: An unauthenticated attacker needs network reachability to a deployed krb5kdc over TCP and the ability to send repeated, syntactically valid, large AS-REQ or TGS-REQ messages containing a very large PrincipalName.name-string SEQUENCE OF GeneralString. No credentials or user interaction are required. Component affected: krb5 SRPM; src/lib/krb5/asn.1/asn1encode.c in decodesequenceof(), reachable from src/kdc/dispatch.c during decodekrb5asreq() and decodekrb5tgsreq(). One practical trigger is PrincipalName.name-string in src/lib/krb5/asn.1/asn1kencode.c. Version affected: krb5-1.21.3-8.el100 when deployed with the KDC service reachable over TCP 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:N/UI:N/S:U/C:N/I:N/A:L - 5.3 (MEDIUM) AV:N - The expensive decode path is reachable over the network through KDC TCP request handling. AC:L - The attacker only needs to send crafted large AS-REQ or TGS-REQ messages with many short sequence elements; no race or unusual preconditions are established. PR:N - The affected decode path runs before authentication. UI:N - No user interaction is required. S:U - The impact is limited to the KDC service within its own security scope. C:N - No confidentiality impact is shown. I:N - No integrity impact is shown. A:L - The availability impact is real but bounded by the roughly 1 MiB request cap and TCP/RPC active-connection limits; the evidence supports practical service degradation and CPU exhaustion, not permanent or system-wide loss. Impact: Important. The issue enables unauthenticated remote denial of service against a deployed KDC over TCP. Although the CVSS availability metric is Low because the work per request is bounded by request-size and connection limits, Red Hat guidance classifies remote denial of service by remote users as Important; the evidence does not support Critical because no confidentiality, integrity, or code-execution impact is shown. Embargo: no Reason: This is a bounded, availability-only issue with practical operational mitigations, so it does not present the same silent-compromise risk that usually justifies embargo for confidentiality, integrity, or code-execution flaws. Acknowledgement: Aisle Research Vulnerability Details: decodesequenceof() grows the destination array by one element per loop iteration: c / src/lib/krb5/asn.1/asn1encode.c / while (len > 0) { ... newseq = realloc(seq, (count + 1) elemtype->size); if (newseq == NULL) { ret = ENOMEM; goto error; } seq = newseq; ... ret = decodeatype(&t, contents, clen, elemtype, elem); ... count++; } The KDC decodes AS-REQ and TGS-REQ messages before authentication: c / src/kdc/dispatch.c / if (krb5istgsreq(pkt)) retval = decodekrb5tgsreq(pkt, &req); else if (krb5isasreq(pkt)) retval = decodekrb5asreq(pkt, &req); One practical trigger is PrincipalName.name-string, which is defined as a counted SEQUENCE OF GeneralString: c / src/lib/krb5/asn.1/asn1kencode.c / DEFCNFIELD(princname1, krb5principaldata, data, length, 1, cseqofgstringdata); KDC TCP input accepts messages up to approximately 1,048,572 bytes of payload, and the server code also enforces a TCP/RPC active-connection cap of 45. Those bounds limit the worst case, but they do not remove the core behavior: a remote attacker can still force one realloc() per decoded element in a pre-auth KDC path by submitting repeated near-cap TCP requests with a very large number of short principal components. The result is attacker-controlled CPU consumption and degraded KDC availability before authentication or request policy checks occur. The available evidence supports this issue for the KDC TCP path. This report does not rely on equivalent reachability over UDP-sized requests, and it does not assert comparable unauthenticated reachability for other daemons. Steps to reproduce: 1. Build and run krb5kdc from krb5-1.21.3-8.el100 with its TCP listener reachable on port 88/TCP. 2. Craft an AS-REQ or TGS-REQ where PrincipalName.name-string contains a very large number of short GeneralString elements, keeping the overall request size just below the TCP payload cap of 1,048,572 bytes. 3. Send the crafted requests repeatedly over TCP from one or more clients. 4. Observe elevated CPU usage in krb5kdc during ASN.1 decode, before authentication completes, together with degraded response time for legitimate requests. 5. Instrument decodesequenceof() if needed and confirm that the number of realloc() calls grows with the number of elements in the sequence. Mitigation: Until a fix is available, limit KDC TCP exposure to trusted networks and apply network-level rate limiting or filtering for repeated large Kerberos TCP requests. If the deployment can safely avoid accepting untrusted KDC TCP traffic, that reduces exposure, but this is only a mitigation and not a code-level fix. Proposed Fix: Grow the destination buffer geometrically instead of by one element per iteration, and optionally shrink it once after decoding completes. diff — a/src/lib/krb5/asn.1/asn1encode.c +++ b/src/lib/krb5/asn.1/asn1encode.c @@ static krb5errorcode decodesequenceof(const uint8t asn1, sizet len, const struct atypeinfo elemtype, void seqout, sizet countout) { krb5errorcode ret; void seq = NULL, elem, newseq; const uint8t contents; sizet clen, count = 0; + sizet clen, count = 0, capacity = 0, newcap; taginfo t; @@

newseq = realloc(seq, (count + 1) elemtype->size);

if (newseq == NULL) {

ret = ENOMEM;

goto error; + if (count == capacity) { + newcap = (capacity == 0) ? 8 : capacity 2; + if (newcap < count + 1 || newcap > SIZEMAX / elemtype->size) { + ret = ASN1OVERFLOW; + goto error; + } + newseq = realloc(seq, newcap elemtype->size); + if (newseq == NULL) { + ret = ENOMEM; + goto error; + } + seq = newseq; + capacity = newcap; }

seq = newseq; elem = (char )seq + count elemtype->size; memset(elem, 0, elemtype->size); ret = decodeatype(&t, contents, clen, elemtype, elem); if (ret) goto error; count++; } + if (count > 0 && count < capacity) { + newseq = realloc(seq, count elemtype->size); + if (newseq != NULL) + seq = newseq; + } seqout = seq; countout = count; return 0;

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

1 / 3
Source: Red Hat
First published (updated )
Severity
7.5
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: Unauthenticated CPU DoS in AUTHGSSAPI client cleanup (svcauthgssapi.c): quadratic cleanup of expired AUTHGSSAPI client state can be triggered remotely by accumulating partial AUTHGSSAPIINIT entries and then forcing rescans of mixed live and expired records. Requirements to exploit: Network reachability to a service shipped in this SRPM that accepts the legacy AUTHGSSAPI server path, such as kadmind; no credentials or user interaction are required, but the attacker must sustain crafted AUTHGSSAPIINIT traffic across the INITIATIONTIMEOUT window to build up expiring client records. Component affected: krb5-1.21.3-8.el100, src/lib/rpc/svcauthgssapi.c (cleanclient(), createclient(), and pre-auth AUTHGSSAPIINIT handling) Version affected: krb5-1.21.3-8.el100 when a network-reachable service from this SRPM uses the legacy AUTHGSSAPI server path, such as kadmind 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:N/UI:N/S:U/C:N/I:N/A:H - 7.5 (HIGH) AV:N - The issue is triggered by network requests to a service such as kadmind. AC:L - The attacker only needs repeated unauthenticated AUTHGSSAPIINIT requests over the normal timeout window; no race or special environment is required. PR:N - No prior authentication is needed to create the partial client records involved in cleanup. UI:N - The attack is fully programmatic and does not require user participation. S:U - The impact is confined to the vulnerable 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 - Cleanup can be forced into excessive CPU work, causing prolonged loss of service availability. Impact: Important. This matches Red Hat's Important rating because the available evidence supports an unauthenticated remote denial of service against a network-reachable service from this SRPM that uses the legacy AUTHGSSAPI path. Critical is not appropriate because no confidentiality, integrity, or code-execution impact is shown. Embargo: no Reason: The issue is availability-only, and exploitation still depends on a reachable service exposing legacy AUTHGSSAPI plus sustained request shaping over the initiation timeout window. Restricting access to kadmind or similar RPC services provides an operational mitigation while a fix is prepared. Acknowledgement: Aisle Research Vulnerability Details: cleanclient() removes expired AUTHGSSAPI client state, but after deleting one expired entry it restarts scanning from the head of the global client list: c static void cleanclient(void) { svcauthgssapidata clientdata; clientlist c; c = clients; while (c) { clientdata = c->client; if (clientdata->expiration < time(0)) { destroyclient(clientdata); c = clients; / start over, just to be safe / } else { c = c->next; } } } New client records are prepended to that list: c if (clients == NULL) clients = c; else { c->next = clients; clients = c; } Unauthenticated AUTHGSSAPIINIT handling creates a client record before context establishment succeeds: c / clean up expired entries / cleanclient(); if (creds.authmsg && rqst->rqproc == AUTHGSSAPIINIT) { clientdata = createclient(); ... } If gssacceptseccontext() later fails, the partial record remains until timeout-based cleanup rather than being destroyed immediately. Because newer entries are added at the head and older entries expire at the tail, an attacker can shape a list with a live prefix and an expired suffix. Each expired entry then causes another scan across the live prefix, turning one cleanup pass into quadratic CPU work. In affected deployments, kadmind explicitly enables the older AUTHGSSAPI server path via svcauthgssapisetnames(...), so this is not just unreachable dead code for that service path. Steps to reproduce: 1. Start kadmind (or another service using this AUTHGSSAPI path) with network access to the attacker. 2. Send many RPC calls with oaflavor=AUTHGSSAPI, creds version=2, authmsg=true, rqproc=AUTHGSSAPIINIT, and empty clienthandle. An invalid init token is sufficient if it fails after createclient() executes. 3. Continue sending INIT requests over roughly 15 minutes (INITIATIONTIMEOUT) so older partial entries expire while newer ones remain fresh. 4. Send one additional AUTHGSSAPI request to trigger cleanclient(). 5. Observe a CPU spike and elevated latency while cleanup repeatedly rescans the live prefix of the list. Mitigation: Restrict network access to kadmind and any other service from this SRPM that accepts legacy AUTHGSSAPI requests to trusted management hosts only. If possible, rate-limit or filter repeated unauthenticated AUTHGSSAPIINIT RPC traffic at the network boundary. If a deployment can avoid exposing the legacy AUTHGSSAPI server path and rely on RPCSECGSS instead, that would reduce exposure, although the available material does not establish a universal supported switch for every packaged deployment. Proposed Fix: This patch removes head-restart behavior and list rescans by unlinking expired entries in-place via a pointer-to-pointer walk, while preserving existing destroyclient() behavior for other callers. diff diff --git a/src/lib/rpc/svcauthgssapi.c b/src/lib/rpc/svcauthgssapi.c — a/src/lib/rpc/svcauthgssapi.c +++ b/src/lib/rpc/svcauthgssapi.c @@ -104,6 +104,7 @@ static svcauthgssapidata getclient (gssbuffert clienthandle); static void destroyclient (svcauthgssapidata clientdata); +static void freeclientdata(svcauthgssapidata clientdata); static void cleanclient(void), cleanup(void); static void clientexpire (svcauthgssapidata clientdata, uint32t exp); @@ -818,6 +819,29 @@ static svcauthgssapidata getclient(gssbuffert clienthandle) freed. / static void destroyclient(svcauthgssapidata clientdata) +{ + clientlist c, c2; + + if (clients == NULL) { + PRINTF(("destroyclient: called on empty database\n")); + abort(); + } else if (clients->client == clientdata) { + c = clients; + clients = clients->next; + free(c); + } else { + c2 = clients; + c = clients->next; + while (c) { + if (c->client == clientdata) { + c2->next = c->next; + free(c); + goto unlinked; + } + c2 = c; + c = c->next; + } + PRINTF(("destroyclient: clienthandle delete failed\n")); + abort(); + } +unlinked: + freeclientdata(clientdata); +} + +static void freeclientdata(svcauthgssapidata clientdata) { OMuint32 gssstat, minorstat; gssbufferdesc outbuf;

clientlist c, c2; @@ -841,31 +865,6 @@ static void destroyclient(svcauthgssapidata clientdata) if (clientdata->prevverf.length != 0) gssreleasebuffer(&minorstat, &clientdata->prevverf);

if (clients == NULL) {

PRINTF(("destroyclient: called on empty database\n"));

abort();

} else if (clients->client == clientdata) {

c = clients;

clients = clients->next;

free(c);

} else {

c2 = clients;

c = clients->next;

while (c) {

if (c->client == clientdata) {

c2->next = c->next;

free(c);

goto done;

} else {

c2 = c;

c = c->next;

}

}

PRINTF(("destroyclient: clienthandle delete failed\n"));

abort();

} - -done: - LPRINTF(2, ("destroyclient: client %d destroyed\n", clientdata->key));

free(clientdata); @@ -895,25 +894,27 @@ static void cleanclient(void) { svcauthgssapidata clientdata; clientlist c; + clientlist pp, cur; + timet now;

PRINTF(("cleanclient: starting\n")); c = clients;

while (c) {

clientdata = c->client; + now = time(0); + pp = &clients; + while ((cur = pp) != NULL) { + clientdata = cur->client;

LPRINTF(2, ("cleanclient: clientdata = %p\n", (void ) clientdata)); if (clientdata->expiration < time(0)) { + if (clientdata->expiration < now) { PRINTF(("cleanclient: client %d expired\n", clientdata->key));

destroyclient(clientdata);

c = clients; / start over, just to be safe / + pp = cur->next; + free(cur); + freeclientdata(clientdata); } else {

c = c->next; + pp = &cur->next; } } - PRINTF(("cleanclient: done\n")); }

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

1 / 3
Source: Red Hat
First published (updated )
Severity
7.5
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: Unbounded Memory Leak in clnttcpcall on XID Mismatch (plus retry leak on AUTHREFRESH): a malicious RPC peer or on-path attacker can cause unbounded client-side memory growth and denial of service by sending accepted TCP RPC replies with mismatched transaction IDs and non-empty verifiers. Requirements to exploit: An application using the TCP RPC client path in krb5-1.21.3-8.el100 must issue a call through clnttcpcall, and the attacker must be able to act as the RPC server or inject syntactically valid reply records on the connection before a matching reply is processed. Component affected: krb5-1.21.3-8.el100, src/lib/rpc/clnttcp.c, clnttcpcall (with verifier allocation reached through xdropaqueauth() and xdrbytes()) Version affected: krb5-1.21.3-8.el100 when the TCP RPC client path in clnttcpcall is used 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:N/UI:N/S:U/C:N/I:N/A:H - 7.5 (HIGH) AV:N - A malicious RPC peer, or an attacker able to inject replies on the network path, can trigger the flaw remotely. AC:L - The attack requires only syntactically valid REPLY messages with a mismatched rmxid and a non-empty verifier. PR:N - No privileges on the client are required. UI:N - No additional user interaction is required once the vulnerable client performs the RPC call. S:U - The impact is confined to the client process using the affected library path. C:N - No confidentiality impact is established by the available evidence. I:N - No integrity impact is established by the available evidence. A:H - Each mismatched accepted reply can leak up to MAXAUTHBYTES (400) and the mismatch loop is unbounded for the duration of the call, allowing sustained memory growth and possible process termination. Impact: Moderate. Red Hat classifies remote denial-of-service issues as Important when they are easy and broadly exploitable, but this case is narrower: it affects a specific client-side RPC path, requires an attacker-controlled or intercepted peer, and the demonstrated consequence is denial of service of the consuming client process only. The available evidence does not establish confidentiality, integrity, or broader system compromise. Embargo: no Reason: This is an availability-only, client-side issue that requires a malicious RPC server or an on-path attacker while the affected TCP RPC client path is in use; the current evidence does not show broad compromise or wormable behavior. Acknowledgement: Aisle Research Vulnerability Details: In clnttcpcall, reply headers are decoded in a loop until replymsg.rmxid == xid. For each iteration, replymsg.acptedrply.arverf is reset to gssrpcnullauth before xdrreplymsg() decodes the reply. When a syntactically valid accepted reply carries a non-matching XID, the loop continues without freeing the verifier buffer that may have been allocated during decode. c while (TRUE) { replymsg.acptedrply.arverf = gssrpcnullauth; replymsg.acptedrply.arresults.where = NULL; replymsg.acptedrply.arresults.proc = xdrvoid; if (! xdrrecskiprecord(xdrs)) return (ct->cterror.restatus); / now decode and validate the response header / if (! xdrreplymsg(xdrs, &replymsg)) { / Free some stuff allocated by xdrreplymsg() to avoid leaks, since it may allocate memory from partially successful decodes. / enum xdrop op = xdrs->xop; xdrs->xop = XDRFREE; xdrreplymsg(xdrs, &replymsg); xdrs->xop = op; if (ct->cterror.restatus == RPCSUCCESS) continue; return (ct->cterror.restatus); } if (replymsg.rmxid == xid) break; }

The final verifier cleanup runs only after the loop exits, and the retry path can also bypass that cleanup: c else { / maybe our credentials need to be refreshed ... / if (refreshes-- && AUTHREFRESH(h->clauth, &replymsg)) goto callagain; } / free verifier ... / if ((replymsg.rmreply.rpstat == MSGACCEPTED) && (replymsg.acptedrply.arverf.oabase != NULL)) { xdrs->xop = XDRFREE; (void)xdropaqueauth(xdrs, &(replymsg.acptedrply.arverf)); } xdropaqueauth() decodes arverf through xdrbytes(), which allocates oabase on decode and releases it only under XDRFREE. On an XID mismatch, the next loop iteration overwrites arverf before that free occurs, so the previous pointer is lost. A second leak exists when AUTHREFRESH() succeeds and jumps to callagain before verifier cleanup. The retry-path leak is bounded by the refresh count and is secondary; the main issue is the unbounded mismatch loop. The available evidence supports availability impact only. Steps to reproduce: 1. Build with ASan, or run under Valgrind, and exercise any client path that uses clnttcpcall. 2. Connect the client to a controlled TCP RPC server, or position an on-path interceptor, that repeatedly sends syntactically valid REPLY records with rmdirection = REPLY, rpstat = MSGACCEPTED, arverf.oalength > 0 (up to MAXAUTHBYTES), and rmxid != client xid. 3. Keep sending mismatched replies while the client waits for the legitimate response. 4. Observe monotonic memory growth in the client process through RSS, ASan, or Valgrind. 5. Optionally, return replies that trigger an auth error followed by a successful AUTHREFRESH() to reproduce the retry-path leak. Mitigation: No complete runtime mitigation is established in the package. Exposure can be reduced by limiting this TCP RPC client path to trusted servers and protected networks, and by using conservative RPC timeouts so a waiting call cannot be held open indefinitely. These measures reduce exposure but do not remove the underlying leak. Proposed Fix: Free the verifier for non-matching accepted replies before the next decode, and free it before retrying callagain on successful AUTHREFRESH(). diff diff --git a/src/lib/rpc/clnttcp.c b/src/lib/rpc/clnttcp.c — a/src/lib/rpc/clnttcp.c +++ b/src/lib/rpc/clnttcp.c @@ -320,6 +320,15 @@ clnttcpcall(CLIENT h, rpcproct proc, xdrproct xdrargs, void argsptr, if (replymsg.rmxid == xid) break; + / Free verifier from non-matching replies before next decode. / + if ((replymsg.rmreply.rpstat == MSGACCEPTED) && + (replymsg.acptedrply.arverf.oabase != NULL)) { + enum xdrop op = xdrs->xop; + xdrs->xop = XDRFREE; + (void)xdropaqueauth(xdrs, &(replymsg.acptedrply.arverf)); + xdrs->xop = op; + } } @@ -340,8 +349,18 @@ clnttcpcall(CLIENT h, rpcproct proc, xdrproct xdrargs, void argsptr, else { / maybe our credentials need to be refreshed ... / if (refreshes- && AUTHREFRESH(h->clauth, &replymsg)) + if (refreshes-- && AUTHREFRESH(h->clauth, &replymsg)) { + / Free verifier before retrying callagain. / + if ((replymsg.rmreply.rpstat == MSGACCEPTED) && + (replymsg.acptedrply.arverf.oabase != NULL)) { + enum xdrop op = xdrs->xop; + xdrs->xop = XDRFREE; + (void)xdropaqueauth(xdrs, + &(replymsg.acptedrply.arverf)); + xdrs->xop = op; + } goto callagain; + } } ------ This report was generated using AI technology. Always review AI-generated content prior to use

1 / 2
Source: Red Hat
First published (updated )
Severity
7.5
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: RPCSECGSS Auth-Flavor Switching Causes Unbounded Per-Connection Memory Leak (Unauthenticated DoS): switching a persistent TCP connection from RPCSECGSS to AUTHNONE, AUTHUNIX, or AUTHSHORT can orphan heap-backed auth state and let an unauthenticated remote client exhaust server memory. Requirements to exploit: The attacker must be able to reach a service built from krb5-1.21.3-8.el100 that uses the src/lib/rpc GSS-RPC server path over a long-lived TCP connection with RPCSECGSS enabled. No prior authentication or user interaction is required. Component affected: krb5-1.21.3-8.el100 GSS-RPC server authentication lifecycle in src/lib/rpc, notably svcdoxprt() in svc.c, gssrpcauthenticate() in svcauth.c, gssrpcsvcauthgss() in svcauthgss.c, and the non-GSS handlers in svcauthnone.c and svcauthunix.c. Version affected: krb5-1.21.3-8.el100 (reachable when a service from this SRPM exposes the GSS-RPC server path over persistent TCP with RPCSECGSS enabled) 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:N/UI:N/S:U/C:N/I:N/A:H - 7.5 (HIGH) AV:N - The attack is performed by sending RPC traffic over the network to an exposed service. AC:L - Once the affected TCP GSS-RPC path is reachable, alternating auth flavors on one connection is straightforward and repeatable. PR:N - The leak can be triggered before successful authentication is established. UI:N - No user interaction is required. S:U - The impact is limited to the vulnerable service's own security scope. C:N - No confidentiality impact is demonstrated. I:N - No integrity impact is demonstrated. A:H - Repetition can drive unbounded memory growth until the service becomes unavailable or is terminated. Impact: Important. The demonstrated effect is an unauthenticated remote denial of service through memory exhaustion on a network-reachable service, which aligns with Red Hat's Important rating for remote DoS. It is not Critical because no system compromise or confidentiality/integrity impact is shown, and reachability depends on a deployment exposing the affected RPCSECGSS TCP path. Embargo: no Reason: This is an availability-only issue with configuration-dependent reachability, and administrators can reduce exposure by restricting access to the affected service. The available evidence does not show code execution or silent data compromise that would strongly justify delayed public disclosure. Acknowledgement: Aisle Research Vulnerability Details: The issue is a lifecycle mismatch for xprt->xpauth. gssrpcsvcauthgss() allocates heap-backed SVCAUTH/GSS private state and stores it on the transport. svcdoxprt() intentionally preserves RPCSECGSS auth handles across requests, but later non-GSS authenticators overwrite the same pointer with the static &svcauthnone handle without first calling SVCAUTHDESTROY(). After the overwrite, the original heap object is no longer reachable and leaks until process exit. In src/lib/rpc/svcauthgss.c, RPCSECGSS authentication attaches per-connection auth state to the transport: c if (rqst->rqxprt->xpauth == NULL || rqst->rqxprt->xpauth == &svcauthnone) { ... auth->svcahops = &svcauthgssops; SVCAUTHPRIVATE(auth) = gd; rqst->rqxprt->xpauth = auth; } In src/lib/rpc/svc.c, non-GSS auth handles are nulled at request teardown, while GSS handles are intentionally retained: c } else if ((xprt->xpauth != NULL) && (xprt->xpauth->svcahops != &svcauthgssops)) { xprt->xpauth = NULL; } In src/lib/rpc/svcauthnone.c, and likewise in gssrpcsvcauthunix() and gssrpcsvcauthshort(), a later non-GSS request overwrites the transport pointer: c rqst->rqxprt->xpauth = &svcauthnone; An unauthenticated client can therefore keep one TCP connection open, send an RPCSECGSS INIT or CONTINUEINIT request to allocate xpauth, then switch to AUTHNONE, AUTHUNIX, or AUTHSHORT on the same connection to orphan that state. Repeating the sequence causes monotonic heap/RSS growth bounded only by available memory. The available evidence supports availability impact only. Steps to reproduce: 1. Run a service built from krb5-1.21.3-8.el100 that uses the src/lib/rpc server stack over TCP with RPCSECGSS enabled. 2. Keep a single TCP connection open to the service. 3. Send one RPCSECGSS request on that connection, such as INIT or CONTINUEINIT, so gssrpcsvcauthgss() allocates xpauth. 4. On the same connection, send a request using AUTHNONE, AUTHUNIX, or AUTHSHORT so xpauth is overwritten. 5. Repeat steps 3 and 4 in a loop. 6. Observe monotonic memory growth in the server process; repeated switching can eventually exhaust memory and make the service unavailable. Mitigation: Restrict network access to affected GSS-RPC services to trusted clients until a fix is available. Deployments that do not expose the vulnerable TCP GSS-RPC path or do not enable RPCSECGSS are not reachable through this issue. If memory growth is observed, restart the affected service to reclaim leaked memory. Proposed Fix: Centralize cleanup in gssrpcauthenticate() before dispatching to non-RPCSECGSS authenticators so auth-flavor switching cannot orphan the previous heap allocation. diff diff --git a/src/lib/rpc/svcauth.c b/src/lib/rpc/svcauth.c — a/src/lib/rpc/svcauth.c +++ b/src/lib/rpc/svcauth.c @@ -38,6 +38,7 @@ / #include <gssrpc/rpc.h> +extern struct svcauthops svcauthgssops; / Server side authenticators are called from authenticate by @@ -92,6 +93,14 @@ gssrpcauthenticate( rqst->rqxprt->xpverf.oalength = 0; credflavor = rqst->rqcred.oaflavor; nodispatch = FALSE; + + / Drop stale RPCSECGSS auth state if client switches flavor. / + if (rqst->rqxprt->xpauth != NULL && + rqst->rqxprt->xpauth->svcahops == &svcauthgssops && + credflavor != RPCSECGSS) { + SVCAUTHDESTROY(rqst->rqxprt->xpauth); + rqst->rqxprt->xpauth = NULL; + } + for (i = 0; i < svcauthnum; i++) { if (credflavor == svcauthsw[i].flavor && svcauthsw[i].authenticator != NULL) {

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

1 / 2
Source: Red Hat
First published (updated )
Severity
7.5
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: Pre-auth memory leak in legacy AUTHGSSAPI INIT path (svcauthgssapi.c) enables remote DoS: crafted AUTHGSSAPIINIT requests can leak decoded token memory on early error exits and exhaust an affected network service that accepts legacy AUTHGSSAPI. Requirements to exploit: The attacker needs network access to a service built from krb5-1.21.3-8.el100 that accepts legacy AUTHGSSAPI and processes AUTHGSSAPIINIT before authentication. No valid credentials, completed GSS context, or user interaction are required, but the request must be syntactically valid enough for svcgetargs() to decode callarg; larger token payloads increase the leak rate within the request sizes the exposed service accepts. Component affected: krb5-1.21.3-8.el100, legacy AUTHGSSAPI server-side INIT handling in src/lib/rpc/svcauthgssapi.c, function gssrpcsvcauthgssapi() Version affected: krb5-1.21.3-8.el100 when deployed with a service that accepts legacy AUTHGSSAPI requests 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:N/UI:N/S:U/C:N/I:N/A:H - 7.5 (HIGH) AV:N - The issue is reachable over network RPC in services that expose the vulnerable legacy AUTHGSSAPI path. AC:L - Once that path is exposed, sending a decodable AUTHGSSAPIINIT request with an unsupported version is straightforward. PR:N - The leak occurs before authentication completes and does not require valid credentials. UI:N - No user interaction is needed. S:U - The impact is contained to the vulnerable service. C:N - No confidentiality impact is demonstrated. I:N - No integrity impact is demonstrated. A:H - Repeated requests can accumulate leaked memory and deny service through memory exhaustion. Impact: Important. Red Hat guidance classifies flaws that allow remote users to cause a denial of service as Important, and this issue permits unauthenticated remote memory exhaustion against an affected network service. The legacy nature of the AUTHGSSAPI path narrows exposure, but the demonstrated consequence is still a direct remote availability loss rather than a merely theoretical source-only defect. Embargo: no Reason: This is an availability-only flaw in a legacy authentication path, the fix is small and low risk, and operators can reduce exposure by restricting access to affected services while a package update is prepared. Acknowledgement: Aisle Research Vulnerability Details: During pre-auth AUTHGSSAPIINIT handling, gssrpcsvcauthgssapi() decodes attacker-controlled input into callarg. Two subsequent error branches return through error: before the only INIT-path xdrfree((xdrproct)xdrauthgssapiinitarg, &callarg); is reached, and the shared error: block frees only creds. As a result, the decoded token buffer can be leaked once per request. c / call is for us, deserialize arguments / memset(&callarg, 0, sizeof(callarg)); if (! svcgetargs(rqst->rqxprt, (xdrproct)xdrauthgssapiinitarg, &callarg)) { PRINTF(("svcauthgssapi: cannot decode args\n")); LOGMISCERR("protocol error in procedure arguments"); ret = AUTHBADCRED; goto error; } ... switch (callarg.version) { ... default: PRINTF(("svcauthgssapi: bad GSSAPIINIT version\n")); LOGMISCERR("unsupported GSSAPIINIT version"); ret = AUTHBADCRED; goto error; } ... if (rqst->rqxprt->xpladdrlen > 0) { bindings.acceptoraddrtype = GSSCAFINET; bindings.acceptoraddress.length = 4; bindings.acceptoraddress.value = &rqst->rqxprt->xpladdr.sinaddr.saddr; } else { LOGMISCERR("cannot get local address"); ret = AUTHFAILED; goto error; } ... / done with call args / xdrfree((xdrproct)xdrauthgssapiinitarg, &callarg); ... error: if (creds.clienthandle.length != 0) { PRINTF(("svcauthgssapi: freeing clienthandle len %d\n", (int) creds.clienthandle.length)); xdrfree((xdrproct)xdrauthgssapicreds, &creds); } PRINTF(("\n")); return ret; The unsupported-version branch is sufficient to trigger the leak and does not depend on the less common xpladdrlen <= 0 case. The available package context also shows server-side acceptance of AUTHGSSAPI in kadmind, so this is not limited to unreachable library code. Transport cleanup does not resolve this case because the relevant cleanup happens only on decode failure, not on later application-auth error exits after callarg has already been allocated. Steps to reproduce: 1. Run a service from krb5-1.21.3-8.el100 that accepts legacy AUTHGSSAPI requests, such as kadmind, with ASAN or RSS monitoring enabled. 2. Send RPC requests with auth flavor AUTHGSSAPI, procedure AUTHGSSAPIINIT, and wrapper fields that allow svcgetargs(..., xdrauthgssapiinitarg, &callarg) to decode successfully, such as creds.version=2, authmsg=true, and an empty clienthandle. 3. Set callarg.version to an unsupported value such as 5, and include a large token so the decoded callarg.token allocation is substantial. 4. Repeat the request and observe monotonic memory growth without a corresponding free for the decoded INIT token. 5. Confirm the request exits through the unsupported-version branch, or the xpladdrlen <= 0 branch, before reaching the sole INIT-path xdrfree((xdrproct)xdrauthgssapiinitarg, &callarg);. Mitigation: Until a fixed package is available, restrict network access to services that accept legacy AUTHGSSAPI to trusted management networks and monitor or rate-limit repeated failing AUTHGSSAPIINIT traffic where possible. If operationally feasible, prefer deployments that do not expose the legacy AUTHGSSAPI path to untrusted clients. Proposed Fix: Free callarg before each early goto error that occurs after successful INIT decode. diff diff --git a/src/lib/rpc/svcauthgssapi.c b/src/lib/rpc/svcauthgssapi.c — a/src/lib/rpc/svcauthgssapi.c +++ b/src/lib/rpc/svcauthgssapi.c @@ -337,6 +337,7 @@ default: PRINTF(("svcauthgssapi: bad GSSAPIINIT version\n")); LOGMISCERR("unsupported GSSAPIINIT version"); + xdrfree((xdrproct)xdrauthgssapiinitarg, &callarg); ret = AUTHBADCRED; goto error; } @@ -361,6 +362,7 @@ } else { LOGMISCERR("cannot get local address"); + xdrfree((xdrproct)xdrauthgssapiinitarg, &callarg); ret = AUTHFAILED; goto error; } ------ This report was generated using AI technology. Always review AI-generated content prior to use

1 / 2
Source: Red Hat
First published (updated )
Severity
7

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: Unauthenticated Memory-Exhaustion DoS in kadmind legacy AUTHGSSAPI handshake (svcauthgssapi.c): repeated unauthenticated AUTHGSSAPIINIT failures can allocate per-client state that is retained until timeout-based cleanup, allowing remote memory-pressure denial of service. Requirements to exploit: Network reachability to a kadmind admin RPC endpoint and the ability to send crafted unauthenticated AUTHGSSAPIINIT requests that reach the legacy server-side AUTHGSSAPI handler; no valid Kerberos credentials or user interaction are required. Component affected: krb5-1.21.3-8.el100, src/lib/rpc/svcauthgssapi.c, gssrpcsvcauthgssapi() legacy AUTHGSSAPI handshake path reachable via kadmind Version affected: krb5-1.21.3-8.el100 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:N/UI:N/S:U/C:N/I:N/A:H - 7.5 (HIGH) AV:N - The attack is delivered over the network to a reachable kadmind RPC service. AC:L - Repeated malformed AUTHGSSAPIINIT traffic is sufficient; no race or unusual precondition is established. PR:N - No Kerberos credentials or other prior authentication are required. UI:N - No user interaction is needed. S:U - The impact stays within the authority of the vulnerable service. C:N - No confidentiality impact is established from the available evidence. I:N - No integrity impact is established from the available evidence. A:H - Repeated retained allocations can drive sustained memory growth and deny service. Impact: Important. Red Hat classifies flaws that allow remote users to cause a denial of service as Important when they can compromise availability of resources. Here, the established effect is unauthenticated remote memory exhaustion against a reachable kadmind service. Critical is not supported because the evidence does not show arbitrary code execution or broader system compromise, and the demonstrated impact is availability-only. Embargo: no Reason: The established impact is denial of service on an administrative service, and exposure can be materially reduced by restricting network access to kadmind while a fix is prepared. Private coordination is still useful, but the currently established impact does not strongly support an extended embargo. Acknowledgement: Aisle Research Vulnerability Details: In gssrpcsvcauthgssapi(), an AUTHGSSAPIINIT request with an empty client handle creates new per-client state before context establishment. That state is inserted into the global clients list and given a 15-minute initiation timeout. When context establishment fails, the function sends an error response and returns through error: without destroying the just-created entry. c if (creds.authmsg && rqst->rqproc == AUTHGSSAPIINIT) { ... clientdata = createclient(); ... } c clientdata->expiration = time(0) + INITIATIONTIMEOUT; / 6015 / c if (callres.gssmajor != GSSSCOMPLETE && callres.gssmajor != GSSSCONTINUENEEDED) { ... svcsendreply(...); nodispatch = TRUE; ret = AUTHOK; goto error; / no destroyclient(clientdata) / } Repeated unauthenticated failures therefore accumulate retained svcauthgssapidata entries until timeout-based cleanup runs. The same cleanup gap also affects other post-allocation INIT failure paths that return through error: after createclient() has already succeeded, including malformed init arguments or unsupported INIT versions. Based on the available evidence, the established impact is denial of service through attacker-driven memory growth; no confidentiality or integrity impact is established. Steps to reproduce: 1. Run kadmind from this package and ensure the admin RPC service is reachable, typically on 749/tcp. 2. Open one TCP connection to the service. 3. Repeatedly send RPC calls with credential flavor AUTHGSSAPI, procedure AUTHGSSAPIINIT, authmsg = TRUE, an empty clienthandle, and an invalid or malformed init token. Malformed INIT arguments after credential parsing also exercise post-allocation failure handling. 4. Observe that failed INIT requests return an error response while also yielding a fresh clienthandle, indicating that new server-side client state was created. 5. Continue sending failures at a moderate rate and monitor kadmind memory usage. Memory rises and remains elevated until the initiation timeout expires (about 15 minutes), demonstrating unauthenticated memory-pressure denial of service. Mitigation: Restrict network access to the kadmind admin RPC service to trusted management hosts, and apply network filtering or rate limiting for repeated failed AUTHGSSAPIINIT traffic where possible. Until a fix is available, avoid exposing this administrative interface to untrusted networks and monitor kadmind for abnormal memory growth. Proposed Fix: Track whether the current request created a new client entry and destroy that entry on all failure exits so partially initialized state is not left in the global client list. diff — a/src/lib/rpc/svcauthgssapi.c +++ b/src/lib/rpc/svcauthgssapi.c @@ -170,6 +170,7 @@ enum authstat gssrpcsvcauthgssapi( enum authstat ret; OMuint32 retflags; uint32t seqnum; + boolt createdclient = FALSE; @@ -248,6 +249,7 @@ enum authstat gssrpcsvcauthgssapi( if (clientdata == NULL) { ... } + createdclient = TRUE; } else { ... } @@ -461,6 +463,12 @@ enum authstat gssrpcsvcauthgssapi( gssreleasebuffer(&minorstat, &outputtoken); + if (createdclient) { + destroyclient(clientdata); + clientdata = NULL; + rqst->rqxprt->xpauth = &svcauthnone; + createdclient = FALSE; + } svcsendreply(rqst->rqxprt, (xdrproct)xdrauthgssapiinitres, (caddrt) &callres); nodispatch = TRUE; @@ -652,6 +660,12 @@ error: + if (createdclient && clientdata != NULL) { + destroyclient(clientdata); + clientdata = NULL; + rqst->rqxprt->xpauth = &svcauthnone; + createdclient = FALSE; + } if (creds.clienthandle.length != 0) { ... } ------ This report was generated using AI technology. Always review AI-generated content prior to use

First published (updated )
Severity
7

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: Unauthenticated CPU DoS in AUTHGSSAPI client cleanup (svcauthgssapi.c): quadratic cleanup of expired AUTHGSSAPI client state can be triggered remotely by accumulating partial AUTHGSSAPIINIT entries and then forcing rescans of mixed live and expired records. Requirements to exploit: Network reachability to a service shipped in this SRPM that accepts the legacy AUTHGSSAPI server path, such as kadmind; no credentials or user interaction are required, but the attacker must sustain crafted AUTHGSSAPIINIT traffic across the INITIATIONTIMEOUT window to build up expiring client records. Component affected: krb5-1.21.3-8.el100, src/lib/rpc/svcauthgssapi.c (cleanclient(), createclient(), and pre-auth AUTHGSSAPIINIT handling) Version affected: krb5-1.21.3-8.el100 when a network-reachable service from this SRPM uses the legacy AUTHGSSAPI server path, such as kadmind 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:N/UI:N/S:U/C:N/I:N/A:H - 7.5 (HIGH) AV:N - The issue is triggered by network requests to a service such as kadmind. AC:L - The attacker only needs repeated unauthenticated AUTHGSSAPIINIT requests over the normal timeout window; no race or special environment is required. PR:N - No prior authentication is needed to create the partial client records involved in cleanup. UI:N - The attack is fully programmatic and does not require user participation. S:U - The impact is confined to the vulnerable 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 - Cleanup can be forced into excessive CPU work, causing prolonged loss of service availability. Impact: Important. This matches Red Hat's Important rating because the available evidence supports an unauthenticated remote denial of service against a network-reachable service from this SRPM that uses the legacy AUTHGSSAPI path. Critical is not appropriate because no confidentiality, integrity, or code-execution impact is shown. Embargo: no Reason: The issue is availability-only, and exploitation still depends on a reachable service exposing legacy AUTHGSSAPI plus sustained request shaping over the initiation timeout window. Restricting access to kadmind or similar RPC services provides an operational mitigation while a fix is prepared. Acknowledgement: Aisle Research Vulnerability Details: cleanclient() removes expired AUTHGSSAPI client state, but after deleting one expired entry it restarts scanning from the head of the global client list: c static void cleanclient(void) { svcauthgssapidata clientdata; clientlist c; c = clients; while (c) { clientdata = c->client; if (clientdata->expiration < time(0)) { destroyclient(clientdata); c = clients; / start over, just to be safe / } else { c = c->next; } } } New client records are prepended to that list: c if (clients == NULL) clients = c; else { c->next = clients; clients = c; } Unauthenticated AUTHGSSAPIINIT handling creates a client record before context establishment succeeds: c / clean up expired entries / cleanclient(); if (creds.authmsg && rqst->rqproc == AUTHGSSAPIINIT) { clientdata = createclient(); ... } If gssacceptseccontext() later fails, the partial record remains until timeout-based cleanup rather than being destroyed immediately. Because newer entries are added at the head and older entries expire at the tail, an attacker can shape a list with a live prefix and an expired suffix. Each expired entry then causes another scan across the live prefix, turning one cleanup pass into quadratic CPU work. In affected deployments, kadmind explicitly enables the older AUTHGSSAPI server path via svcauthgssapisetnames(...), so this is not just unreachable dead code for that service path. Steps to reproduce: 1. Start kadmind (or another service using this AUTHGSSAPI path) with network access to the attacker. 2. Send many RPC calls with oaflavor=AUTHGSSAPI, creds version=2, authmsg=true, rqproc=AUTHGSSAPIINIT, and empty clienthandle. An invalid init token is sufficient if it fails after createclient() executes. 3. Continue sending INIT requests over roughly 15 minutes (INITIATIONTIMEOUT) so older partial entries expire while newer ones remain fresh. 4. Send one additional AUTHGSSAPI request to trigger cleanclient(). 5. Observe a CPU spike and elevated latency while cleanup repeatedly rescans the live prefix of the list. Mitigation: Restrict network access to kadmind and any other service from this SRPM that accepts legacy AUTHGSSAPI requests to trusted management hosts only. If possible, rate-limit or filter repeated unauthenticated AUTHGSSAPIINIT RPC traffic at the network boundary. If a deployment can avoid exposing the legacy AUTHGSSAPI server path and rely on RPCSECGSS instead, that would reduce exposure, although the available material does not establish a universal supported switch for every packaged deployment. Proposed Fix: This patch removes head-restart behavior and list rescans by unlinking expired entries in-place via a pointer-to-pointer walk, while preserving existing destroyclient() behavior for other callers. diff diff --git a/src/lib/rpc/svcauthgssapi.c b/src/lib/rpc/svcauthgssapi.c — a/src/lib/rpc/svcauthgssapi.c +++ b/src/lib/rpc/svcauthgssapi.c @@ -104,6 +104,7 @@ static svcauthgssapidata getclient (gssbuffert clienthandle); static void destroyclient (svcauthgssapidata clientdata); +static void freeclientdata(svcauthgssapidata clientdata); static void cleanclient(void), cleanup(void); static void clientexpire (svcauthgssapidata clientdata, uint32t exp); @@ -818,6 +819,29 @@ static svcauthgssapidata getclient(gssbuffert clienthandle) freed. / static void destroyclient(svcauthgssapidata clientdata) +{ + clientlist c, c2; + + if (clients == NULL) { + PRINTF(("destroyclient: called on empty database\n")); + abort(); + } else if (clients->client == clientdata) { + c = clients; + clients = clients->next; + free(c); + } else { + c2 = clients; + c = clients->next; + while (c) { + if (c->client == clientdata) { + c2->next = c->next; + free(c); + goto unlinked; + } + c2 = c; + c = c->next; + } + PRINTF(("destroyclient: clienthandle delete failed\n")); + abort(); + } +unlinked: + freeclientdata(clientdata); +} + +static void freeclientdata(svcauthgssapidata clientdata) { OMuint32 gssstat, minorstat; gssbufferdesc outbuf;

clientlist c, c2; @@ -841,31 +865,6 @@ static void destroyclient(svcauthgssapidata clientdata) if (clientdata->prevverf.length != 0) gssreleasebuffer(&minorstat, &clientdata->prevverf);

if (clients == NULL) {

PRINTF(("destroyclient: called on empty database\n"));

abort();

} else if (clients->client == clientdata) {

c = clients;

clients = clients->next;

free(c);

} else {

c2 = clients;

c = clients->next;

while (c) {

if (c->client == clientdata) {

c2->next = c->next;

free(c);

goto done;

} else {

c2 = c;

c = c->next;

}

}

PRINTF(("destroyclient: clienthandle delete failed\n"));

abort();

} - -done: - LPRINTF(2, ("destroyclient: client %d destroyed\n", clientdata->key));

free(clientdata); @@ -895,25 +894,27 @@ static void cleanclient(void) { svcauthgssapidata clientdata; clientlist c; + clientlist pp, cur; + timet now;

PRINTF(("cleanclient: starting\n")); c = clients;

while (c) {

clientdata = c->client; + now = time(0); + pp = &clients; + while ((cur = pp) != NULL) { + clientdata = cur->client;

LPRINTF(2, ("cleanclient: clientdata = %p\n", (void ) clientdata)); if (clientdata->expiration < time(0)) { + if (clientdata->expiration < now) { PRINTF(("cleanclient: client %d expired\n", clientdata->key));

destroyclient(clientdata);

c = clients; / start over, just to be safe / + pp = cur->next; + free(cur); + freeclientdata(clientdata); } else {

c = c->next; + pp = &cur->next; } } - PRINTF(("cleanclient: done\n")); }

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

First published (updated )
Severity
7

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: Authenticated Memory Exhaustion and Leak in RPCSECGSS Unwrapping (xdrrpcgssunwrapdata): authenticated RPCSECGSS 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 RPCSECGSS 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/authgssprot.c:xdrrpcgssunwrapdata via xdrrpcgssbuf, with the allocation behavior in src/lib/rpc/xdr.c:xdrbytes Version affected: krb5-1.21.3-8.el100 when deployed with a service that accepts authenticated RPCSECGSSDATA 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 RPCSECGSS 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 RPCSECGSS 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 RPCSECGSS 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 RPCSECGSS credentials and exposure of a vulnerable RPCSECGSS service, and the demonstrated impact is denial of service rather than code execution or privilege escalation. Acknowledgement: Aisle Research Vulnerability Details: xdrrpcgssunwrapdata decodes attacker-controlled wrapped buffers with maxsize = (unsigned int)-1 for both integrity and privacy services. That value is then passed into xdrbytes, which allocates memory directly from the wire length before MIC verification or unwrap validation completes. c if (svc == RPCSECGSSSVCINTEGRITY) { / Decode databodyinteg. / if (!xdrrpcgssbuf(xdrs, &databuf, (unsigned int)-1)) { logdebug("xdr decode databodyinteg failed"); return (FALSE); } / Decode checksum. / if (!xdrrpcgssbuf(xdrs, &wrapbuf, (unsigned int)-1)) { gssreleasebuffer(&minstat, &databuf); logdebug("xdr decode checksum failed"); return (FALSE); } / Verify checksum and QOP. / majstat = gssverifymic(&minstat, ctx, &databuf, &wrapbuf, &qopstate); free(wrapbuf.value); if (majstat != GSSSCOMPLETE || qopstate != qop) { gssreleasebuffer(&minstat, &databuf); logstatus("gssverifymic", majstat, minstat); return (FALSE); } } else if (svc == RPCSECGSSSVCPRIVACY) { / Decode databodypriv. / if (!xdrrpcgssbuf(xdrs, &wrapbuf, (unsigned int)-1)) { logdebug("xdr decode databodypriv failed"); return (FALSE); } c if (! xdruint(xdrs, sizep)) { return (FALSE); } nodesize = sizep; if ((nodesize > maxsize) && (xdrs->xop != XDRFREE)) { return (FALSE); } / now deal with the actual bytes / switch (xdrs->xop) {

case XDRDECODE: if (nodesize == 0) { return (TRUE); } if (sp == NULL) { cpp = sp = (char )memalloc(nodesize); } Because maxsize is effectively UINTMAX in this call path, the nodesize > maxsize check does not provide a practical bound. The allocation happens before gssverifymic() or gssunwrap(), 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 RPCSECGSS enabled over TCP, for example an administration service using the GSSRPC server path. 2. Establish a valid RPCSECGSS context as an authenticated client. 3. Send an RPCSECGSSDATA request with gcproc = RPCSECGSSDATA and gcsvc = RPCSECGSSSVCINTEGRITY or RPCSECGSSSVCPRIVACY. 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 RPCSECGSS 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/authgssprot.c b/src/lib/rpc/authgssprot.c — a/src/lib/rpc/authgssprot.c +++ b/src/lib/rpc/authgssprot.c @@ -46,6 +46,9 @@ #include <gssapi/gssapi.h> #endif +/ Upper bound for decoded wrapped RPCSECGSS payloads. / +#define RPCSECGSSMAXUNWRAP (16U 1024U 1024U) + boolt xdrrpcgssbuf(XDR xdrs, gssbuffert buf, uint maxsize) { @@ -202,13 +205,18 @@ xdrrpcgssunwrapdata(XDR xdrs, xdrproct xdrfunc, caddrt xdrptr, if (svc == RPCSECGSSSVCINTEGRITY) { / Decode databodyinteg. / - if (!xdrrpcgssbuf(xdrs, &databuf, (unsigned int)-1)) { + if (!xdrrpcgssbuf(xdrs, &databuf, RPCSECGSSMAXUNWRAP)) { logdebug("xdr decode databodyinteg failed"); return (FALSE); } / Decode checksum. / - if (!xdrrpcgssbuf(xdrs, &wrapbuf, (unsigned int)-1)) { + if (!xdrrpcgssbuf(xdrs, &wrapbuf, RPCSECGSSMAXUNWRAP)) { gssreleasebuffer(&minstat, &databuf); + if (wrapbuf.value != NULL) + free(wrapbuf.value); logdebug("xdr decode checksum failed"); return (FALSE); } @@ -225,7 +233,10 @@ xdrrpcgssunwrapdata(XDR xdrs, xdrproct xdrfunc, caddrt xdrptr, } else if (svc == RPCSECGSSSVCPRIVACY) { / Decode databodypriv. / - if (!xdrrpcgssbuf(xdrs, &wrapbuf, (unsigned int)-1)) { + if (!xdrrpcgssbuf(xdrs, &wrapbuf, RPCSECGSSMAXUNWRAP)) { + if (wrapbuf.value != NULL) + free(wrapbuf.value); logdebug("xdr decode databodypriv failed"); return (FALSE); } ------ This report was generated using AI technology. Always review AI-generated content prior to use

First published (updated )
Severity
7

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: Authenticated DoS via Memory Leak in xdrkrb5tldata Decode Error Path: malformed authenticated kadmind RPC requests with non-null tldata can leak heap allocations on decode failure and eventually exhaust process memory. Requirements to exploit: Network reachability to kadmind, valid credentials for a principal able to establish an authenticated RPCSECGSS session to the kadmin RPC service, and the ability to send a malformed request that decodes kadm5principalentrec with non-null tldata. Component affected: krb5-1.21.3-8.el100, src/lib/kadm5/kadmrpcxdr.c, xdrkrb5tldata() in the kadmind request decode path for kadm5principalentrec.tldata. Version affected: krb5-1.21.3-8.el100 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 vulnerable path is reachable over the network through the kadmind RPC service. AC:L - Exploitation only requires sending malformed tldata that fails decoding after allocation. PR:L - A valid authenticated RPCSECGSS session to kadmind is required; the leak occurs during request decoding rather than after successful completion of the requested administrative operation. UI:N - No user interaction is required once the attacker can send requests. S:U - The impact is confined to the kadmind service boundary. C:N - No confidentiality impact is established by the available evidence. I:N - No integrity impact is established by the available evidence. A:H - Repeated requests can drive unbounded memory growth and deny availability of the long-lived kadmind process. Impact: Important. Red Hat classifies remote denial of service issues as Important when they can readily compromise service availability. This issue allows an authenticated remote user to repeatedly exhaust memory in kadmind through a normal request decode path once a valid session exists. Critical is not appropriate because authentication is required and no code execution, privilege escalation, or broader system compromise is established. Embargo: no Reason: The issue is limited to authenticated availability impact against an administrative service, and operators can reduce exposure by restricting access to kadmind until a fix is available. Acknowledgement: Aisle Research Vulnerability Details: In xdrkrb5tldata(), the XDRDECODE path allocates a new krb5tldata element and decodes its fields before the accumulated list is linked into tldatahead. The affected block is: c case XDRDECODE: tl = NULL; while (1) { if (!xdrbool(xdrs, &more)) return FALSE; if (more == FALSE) break; tl2 = (krb5tldata ) malloc(sizeof(krb5tldata)); if (tl2 == NULL) return FALSE; memset(tl2, 0, sizeof(krb5tldata)); if (!xdrkrb5int16(xdrs, &tl2->tldatatype)) return FALSE; if (!xdrbytes(xdrs, (char )&tl2->tldatacontents, &len, ~0)) return FALSE; tl2->tldatalength = len; tl2->tldatanext = tl; tl = tl2; } tldatahead = tl; break; If xdrbool, xdrkrb5int16, or xdrbytes fails after allocation, the function returns FALSE immediately. At that point, the current tl2 allocation, any tl2->tldatacontents buffer allocated by xdrbytes, and any previously built tl chain are not attached to tldatahead. In the kadmind request path, failed RPC argument decoding is cleaned up through the decoded argument object; because the partially constructed list is never linked into that object, those allocations remain unreachable to normal XDRFREE cleanup and are leaked. The available evidence shows this is reachable with authenticated CREATEPRINCIPAL and MODIFYPRINCIPAL requests that carry non-null rec.tldata. Steps to reproduce: 1. Start kadmind built from krb5-1.21.3-8.el100 with normal RPCSECGSS authentication. 2. Authenticate as any principal able to establish a valid RPCSECGSS session to the kadmin RPC service. 3. Send a CREATEPRINCIPAL or MODIFYPRINCIPAL RPC request containing non-null rec.tldata. 4. In the tldata sequence, set more = TRUE, begin one entry, then truncate or corrupt the stream so decoding fails at xdrkrb5int16 or xdrbytes. 5. Repeat the malformed request and monitor kadmind RSS with ps or /proc/<pid>/status; the process memory grows monotonically across failed decodes. Mitigation: Until a fixed package is available, restrict network access to kadmind to trusted administration hosts, limit which principals can establish authenticated sessions where deployment policy allows, and monitor or restart kadmind if abnormal RSS growth is observed. Disabling kadmind where it is not required removes remote exposure to the vulnerable decode path. Proposed Fix: Route all XDRDECODE failures through a cleanup path that frees the current element and any previously built tldata chain before returning FALSE. diff diff --git a/src/lib/kadm5/kadmrpcxdr.c b/src/lib/kadm5/kadmrpcxdr.c — a/src/lib/kadm5/kadmrpcxdr.c +++ b/src/lib/kadm5/kadmrpcxdr.c @@ -334,27 +334,40 @@ boolt xdrkrb5tldata(XDR xdrs, krb5tldata tldatahead) case XDRDECODE: tl = NULL; + tl = NULL; while (1) { if (!xdrbool(xdrs, &more))

return FALSE; + goto decodefail; if (more == FALSE) break; tl2 = (krb5tldata ) malloc(sizeof(krb5tldata)); if (tl2 == NULL)

return FALSE; + goto decodefail; memset(tl2, 0, sizeof(krb5tldata));

if (!xdrkrb5int16(xdrs, &tl2->tldatatype))

return FALSE;

if (!xdrbytes(xdrs, (char )&tl2->tldatacontents, &len, ~0))

return FALSE; + if (!xdrkrb5int16(xdrs, &tl2->tldatatype)) { + free(tl2); + goto decodefail; + } + if (!xdrbytes(xdrs, (char )&tl2->tldatacontents, &len, ~0)) { + free(tl2->tldatacontents); + free(tl2); + goto decodefail; + } tl2->tldatalength = len;

tl2->tldatanext = tl; tl = tl2; } tldatahead = tl; break; + +decodefail: + while (tl != NULL) { + tl2 = tl->tldatanext; + free(tl->tldatacontents); + free(tl); + tl = tl2; + } + return FALSE; } ------ This report was generated using AI technology. Always review AI-generated content prior to use

First published (updated )
Severity
7

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: KDB keytab memory leak in krb5ktkdbgetentry() error paths (remote DoS): decrypted key material is left allocated when krb5ktkdbgetentry() takes a later error path, allowing repeated remote requests against exposed KDB:-backed service paths to accumulate leaked memory and degrade availability. Requirements to exploit: Network reachability to a deployment of krb5-1.21.3-8.el100 that exposes a service path using the KDB: keytab, the ability to send repeated crafted requests that make krb5ktkdbgetentry() fail after krb5dbedecryptkeydata() succeeds, and enough request volume to accumulate leaked heap memory. Based on the observed request flow, prior authentication is not required to reach the lookup path. Component affected: krb5-1.21.3-8.el100, src/lib/kdb/keytab.c, krb5ktkdbgetentry(); reachable through KDB:-backed administrative/password-change request handling. Version affected: krb5-1.21.3-8.el100 in builds that include the non-LEANCLIENT KDB: keytab code and expose a network-facing service path using KDB: 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:N/UI:N/S:U/C:N/I:N/A:L - 5.3 (MEDIUM) AV:N - The affected lookup path can be reached over the network through exposed KDB:-backed administrative/password-change services. AC:L - No race or special attack condition is established beyond reaching the affected service and causing a post-decrypt error. PR:N - The request reaches keytab lookup before the client is authenticated. UI:N - No user interaction is required. S:U - The impact is limited to the affected service process. C:N - No confidentiality impact is established. I:N - No integrity impact is established. A:L - Repeated requests can leak memory and degrade or eventually interrupt service availability, but the established effect is incremental resource exhaustion. Impact: Important. Red Hat classifies flaws that allow remote users to cause a denial of service as Important. Here, the established impact is remote availability loss against an exposed network service path without prior authentication. This is not Critical because no code execution, confidentiality loss, or broader system compromise is established. The issue is deployment-dependent on use of KDB:-backed service paths, but where those paths are exposed it fits the Important category more closely than Moderate. Embargo: no Reason: The established impact is availability degradation rather than code execution or data compromise, and exposure can be reduced operationally by restricting access to the affected services while a fix is prepared. Acknowledgement: Aisle Research Vulnerability Details: In src/lib/kdb/keytab.c, krb5ktkdbgetentry() decrypts the selected KDB key into entry->key. If a later check fails, execution jumps to error: and returns without releasing that key material: c kerror = krb5dbedecryptkeydata(context, NULL, keydata, &entry->key, NULL); if (kerror) goto error; if (enctype > 0) { kerror = krb5cenctypecompare(context, enctype, entry->key.enctype, &similar); if (kerror) goto error; if (!similar) { kerror = KRB5KDBNOPERMITTEDKEY; goto error; } } / Coerce the enctype of the output keyblock in case we got an

inexact match on the enctype. / entry->key.enctype = enctype;

kerror = krb5copyprincipal(context, principal, &entry->principal); if (kerror) goto error; / Close database / error: krb5dbfreeprincipal(context, dbentry); / krb5dbclosedatabase(context); / return(kerror); The most straightforward post-decrypt failure shown by the code is a non-similar enctype comparison leading to KRB5KDBNOPERMITTEDKEY; an allocation failure in krb5copyprincipal() would have the same leak outcome. The generic keytab dispatch path returns provider errors without reclaiming partially initialized entry state, so once this function returns an error after populating entry->key, the allocation becomes unreachable. A concrete network-facing use of this path exists where the administrative/password-change service resolves KDB: and authenticates incoming requests against it. Based on the available technical evidence, the remote availability impact is well supported for deployments exposing those KDB:-backed service paths. This report does not rely on a broader claim that every Kerberos service path in the package is affected in the same way. Steps to reproduce: 1. Deploy krb5-1.21.3-8.el100 with its database initialized and a network-reachable administrative or password-change service path that uses KDB:. 2. Send repeated AP-REQ requests to that service so it performs krb5ktgetentry() and then krb5ktkdbgetentry() for the service principal. 3. Craft requests so lookup reaches a post-decrypt error after krb5dbedecryptkeydata() succeeds. A non-similar enctype causing KRB5KDBNOPERMITTEDKEY is one concrete condition visible in the code. 4. Observe the daemon's memory usage over many failing requests. Resident memory should grow while the requests continue to fail. 5. Apply the patch below, rebuild, and repeat the same request pattern. Memory growth from this error path should no longer accumulate. Mitigation: Until a fix is shipped, restrict network access to the administrative/password-change interfaces that use KDB:, disable those services if they are not required, and apply rate limiting or ACLs to untrusted sources. If repeated failures have already caused memory growth, restarting the affected daemon recovers the leaked heap state. Proposed Fix: Track whether entry->key has been populated and free it on error before returning. diff diff --git a/src/lib/kdb/keytab.c b/src/lib/kdb/keytab.c — a/src/lib/kdb/keytab.c +++ b/src/lib/kdb/keytab.c @@ -123,6 +123,7 @@ krb5ktkdbgetentry(krb5context incontext, krb5keytab id, krb5keydata keydata; krb5dbentry dbentry; int xrealmtgt; + krb5boolean keypopulated = FALSE; krb5boolean similar; @@ -166,8 +167,10 @@ krb5ktkdbgetentry(krb5context incontext, krb5keytab id, kerror = krb5dbedecryptkeydata(context, NULL, keydata, &entry->key, NULL); if (kerror) goto error; + keypopulated = TRUE; @@ -193,6 +196,8 @@ krb5ktkdbgetentry(krb5context incontext, krb5keytab id, error: + if (kerror && keypopulated) + krb5freekeyblockcontents(context, &entry->key); krb5dbfreeprincipal(context, dbentry); / krb5dbclosedatabase(context); / return(kerror); ------ This report was generated using AI technology. Always review AI-generated content prior to use

First published (updated )
Severity
7

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: RPCSECGSS Auth-Flavor Switching Causes Unbounded Per-Connection Memory Leak (Unauthenticated DoS): switching a persistent TCP connection from RPCSECGSS to AUTHNONE, AUTHUNIX, or AUTHSHORT can orphan heap-backed auth state and let an unauthenticated remote client exhaust server memory. Requirements to exploit: The attacker must be able to reach a service built from krb5-1.21.3-8.el100 that uses the src/lib/rpc GSS-RPC server path over a long-lived TCP connection with RPCSECGSS enabled. No prior authentication or user interaction is required. Component affected: krb5-1.21.3-8.el100 GSS-RPC server authentication lifecycle in src/lib/rpc, notably svcdoxprt() in svc.c, gssrpcauthenticate() in svcauth.c, gssrpcsvcauthgss() in svcauthgss.c, and the non-GSS handlers in svcauthnone.c and svcauthunix.c. Version affected: krb5-1.21.3-8.el100 (reachable when a service from this SRPM exposes the GSS-RPC server path over persistent TCP with RPCSECGSS enabled) 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:N/UI:N/S:U/C:N/I:N/A:H - 7.5 (HIGH) AV:N - The attack is performed by sending RPC traffic over the network to an exposed service. AC:L - Once the affected TCP GSS-RPC path is reachable, alternating auth flavors on one connection is straightforward and repeatable. PR:N - The leak can be triggered before successful authentication is established. UI:N - No user interaction is required. S:U - The impact is limited to the vulnerable service's own security scope. C:N - No confidentiality impact is demonstrated. I:N - No integrity impact is demonstrated. A:H - Repetition can drive unbounded memory growth until the service becomes unavailable or is terminated. Impact: Important. The demonstrated effect is an unauthenticated remote denial of service through memory exhaustion on a network-reachable service, which aligns with Red Hat's Important rating for remote DoS. It is not Critical because no system compromise or confidentiality/integrity impact is shown, and reachability depends on a deployment exposing the affected RPCSECGSS TCP path. Embargo: no Reason: This is an availability-only issue with configuration-dependent reachability, and administrators can reduce exposure by restricting access to the affected service. The available evidence does not show code execution or silent data compromise that would strongly justify delayed public disclosure. Acknowledgement: Aisle Research Vulnerability Details: The issue is a lifecycle mismatch for xprt->xpauth. gssrpcsvcauthgss() allocates heap-backed SVCAUTH/GSS private state and stores it on the transport. svcdoxprt() intentionally preserves RPCSECGSS auth handles across requests, but later non-GSS authenticators overwrite the same pointer with the static &svcauthnone handle without first calling SVCAUTHDESTROY(). After the overwrite, the original heap object is no longer reachable and leaks until process exit. In src/lib/rpc/svcauthgss.c, RPCSECGSS authentication attaches per-connection auth state to the transport: c if (rqst->rqxprt->xpauth == NULL || rqst->rqxprt->xpauth == &svcauthnone) { ... auth->svcahops = &svcauthgssops; SVCAUTHPRIVATE(auth) = gd; rqst->rqxprt->xpauth = auth; } In src/lib/rpc/svc.c, non-GSS auth handles are nulled at request teardown, while GSS handles are intentionally retained: c } else if ((xprt->xpauth != NULL) && (xprt->xpauth->svcahops != &svcauthgssops)) { xprt->xpauth = NULL; } In src/lib/rpc/svcauthnone.c, and likewise in gssrpcsvcauthunix() and gssrpcsvcauthshort(), a later non-GSS request overwrites the transport pointer: c rqst->rqxprt->xpauth = &svcauthnone; An unauthenticated client can therefore keep one TCP connection open, send an RPCSECGSS INIT or CONTINUEINIT request to allocate xpauth, then switch to AUTHNONE, AUTHUNIX, or AUTHSHORT on the same connection to orphan that state. Repeating the sequence causes monotonic heap/RSS growth bounded only by available memory. The available evidence supports availability impact only. Steps to reproduce: 1. Run a service built from krb5-1.21.3-8.el100 that uses the src/lib/rpc server stack over TCP with RPCSECGSS enabled. 2. Keep a single TCP connection open to the service. 3. Send one RPCSECGSS request on that connection, such as INIT or CONTINUEINIT, so gssrpcsvcauthgss() allocates xpauth. 4. On the same connection, send a request using AUTHNONE, AUTHUNIX, or AUTHSHORT so xpauth is overwritten. 5. Repeat steps 3 and 4 in a loop. 6. Observe monotonic memory growth in the server process; repeated switching can eventually exhaust memory and make the service unavailable. Mitigation: Restrict network access to affected GSS-RPC services to trusted clients until a fix is available. Deployments that do not expose the vulnerable TCP GSS-RPC path or do not enable RPCSECGSS are not reachable through this issue. If memory growth is observed, restart the affected service to reclaim leaked memory. Proposed Fix: Centralize cleanup in gssrpcauthenticate() before dispatching to non-RPCSECGSS authenticators so auth-flavor switching cannot orphan the previous heap allocation. diff diff --git a/src/lib/rpc/svcauth.c b/src/lib/rpc/svcauth.c — a/src/lib/rpc/svcauth.c +++ b/src/lib/rpc/svcauth.c @@ -38,6 +38,7 @@ / #include <gssrpc/rpc.h> +extern struct svcauthops svcauthgssops; / Server side authenticators are called from authenticate by @@ -92,6 +93,14 @@ gssrpcauthenticate( rqst->rqxprt->xpverf.oalength = 0; credflavor = rqst->rqcred.oaflavor; nodispatch = FALSE; + + / Drop stale RPCSECGSS auth state if client switches flavor. / + if (rqst->rqxprt->xpauth != NULL && + rqst->rqxprt->xpauth->svcahops == &svcauthgssops && + credflavor != RPCSECGSS) { + SVCAUTHDESTROY(rqst->rqxprt->xpauth); + rqst->rqxprt->xpauth = NULL; + } + for (i = 0; i < svcauthnum; i++) { if (credflavor == svcauthsw[i].flavor && svcauthsw[i].authenticator != NULL) {

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

First published (updated )
Severity
7

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: Pre-auth Memory Leak in RPCSECGSS Credential Decode Failure Path (gssrpcsvcauthgss): malformed unauthenticated RPCSECGSS credentials can leak gcctx allocations on decode failure, allowing gradual memory-exhaustion denial of service. Requirements to exploit: Network reachability to a service from krb5-1.21.3-8.el100 that parses RPCSECGSS credentials before authentication, plus the ability to send repeated malformed RPC requests with a truncated embedded gcctx buffer. No prior authentication or user interaction is required. Component affected: krb5-1.21.3-8.el100, src/lib/rpc/svcauthgss.c, gssrpcsvcauthgss (with the leaking allocation originating from xdrrpcgsscred() via xdrrpcgssbuf() / xdrbytes()) Version affected: krb5-1.21.3-8.el100 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:N/UI:N/S:U/C:N/I:N/A:L - 5.3 (MEDIUM) AV:N - The affected code parses attacker-controlled RPC credential data over the network. AC:L - The failure condition is induced with a malformed but simple truncated credential blob. PR:N - The leak occurs in the pre-authentication credential decode path. UI:N - No user interaction is required. S:U - The impact is limited to the targeted service process. C:N - The available evidence does not show unauthorized data disclosure. I:N - The available evidence does not show data modification or code execution. A:L - Each request leaks only a bounded amount of memory (MAXAUTHBYTES), but repeated requests can accumulate enough loss to degrade or eventually exhaust the service. Impact: Important. Red Hat classifies flaws that allow remote users to cause denial of service as Important, and this issue is reachable before authentication where an exposed RPCSECGSS service path exists. The practical effect established here is gradual availability loss rather than immediate crash or system compromise, because the leak is bounded per request and requires repetition. Embargo: no Reason: The demonstrated impact is availability-only, the leak is gradual, and straightforward mitigations exist by restricting network access to affected RPCSECGSS-enabled administrative services while a fix is prepared. Acknowledgement: Aisle Research Vulnerability Details: In gssrpcsvcauthgss(), a decode failure returns immediately instead of using the existing freegc: cleanup path: c if (!xdrrpcgsscred(&xdrs, gc)) { logdebug("xdrrpcgsscred() failed"); XDRDESTROY(&xdrs); return (AUTHBADCRED); } ... freegc: xdrfree((xdrproct)xdrrpcgsscred, gc); logdebug("returning %d from svcauthgss()", retstat); return (retstat); The decoded gcctx field is populated through xdrrpcgssbuf() and xdrbytes(). On XDRDECODE, xdrbytes() allocates the buffer before it attempts to read the declared opaque bytes. If the embedded RPCSECGSS credential advertises a non-zero gcctx length but truncates the remaining credential bytes, the opaque read can fail after allocation. Because the function returns before xdrfree((xdrproct)xdrrpcgsscred, gc) is reached, that nested allocation is not released on the failing request. The available material further supports that this parser is selected from the server authentication dispatch when cbcred.oaflavor is RPCSECGSS. The resulting leak is bounded per request by the credential-size checks, but repeated malformed unauthenticated requests can cause monotonic memory growth over time. The evidence supports this for deployments that expose an RPCSECGSS-enabled service path, including in-tree administrative paths such as kadmind or iprop; it does not establish that every deployment of the SRPM exposes those paths. Steps to reproduce: 1. Reach a server path built from krb5-1.21.3-8.el100 that accepts RPCSECGSS credentials before authentication. 2. Send an RPC call with cbcred.oaflavor = RPCSECGSS. 3. Keep the outer credential blob within the accepted MAXAUTHBYTES limit so decoding proceeds into the embedded RPCSECGSS credential. 4. Inside the embedded credential, set gcctx to a non-zero declared length but truncate the remaining bytes so allocation occurs and the subsequent opaque-byte read fails. 5. Observe an authentication failure associated with AUTHBADCRED while the service retains the allocation from the failed decode path. 6. Repeat the malformed request and monitor service memory growth over time. Mitigation: Restrict network access to RPCSECGSS-enabled administrative services to trusted clients until a fix is available. Where feasible, do not expose kadmind/iprop-related RPC endpoints to untrusted networks, and apply rate limiting or connection controls to reduce the effect of repeated malformed requests. Proposed Fix: Route the decode-failure path through the existing freegc: cleanup so partially decoded RPCSECGSS credentials are always released. diff diff --git a/krb5-1.21.3/src/lib/rpc/svcauthgss.c b/krb5-1.21.3/src/lib/rpc/svcauthgss.c index <old>..<new> 100644 — a/krb5-1.21.3/src/lib/rpc/svcauthgss.c +++ b/krb5-1.21.3/src/lib/rpc/svcauthgss.c @@ -434,10 +434,12 @@ gssrpcsvcauthgss(struct svcreq rqst, struct rpcmsg msg, rqst->rqcred.oalength, XDRDECODE); logdebug("xdrmemcreate() returned"); if (!xdrrpcgsscred(&xdrs, gc)) { logdebug("xdrrpcgsscred() failed"); XDRDESTROY(&xdrs); return (AUTHBADCRED); + retstat = AUTHBADCRED; + goto freegc; } XDRDESTROY(&xdrs);

An equivalent fix is to call xdrfree((xdrproct)xdrrpcgsscred, gc) immediately before returning AUTHBADCRED. ------ This report was generated using AI technology. Always review AI-generated content prior to use

First published (updated )
Severity
7

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: Pre-auth memory leak in legacy AUTHGSSAPI INIT path (svcauthgssapi.c) enables remote DoS: crafted AUTHGSSAPIINIT requests can leak decoded token memory on early error exits and exhaust an affected network service that accepts legacy AUTHGSSAPI. Requirements to exploit: The attacker needs network access to a service built from krb5-1.21.3-8.el100 that accepts legacy AUTHGSSAPI and processes AUTHGSSAPIINIT before authentication. No valid credentials, completed GSS context, or user interaction are required, but the request must be syntactically valid enough for svcgetargs() to decode callarg; larger token payloads increase the leak rate within the request sizes the exposed service accepts. Component affected: krb5-1.21.3-8.el100, legacy AUTHGSSAPI server-side INIT handling in src/lib/rpc/svcauthgssapi.c, function gssrpcsvcauthgssapi() Version affected: krb5-1.21.3-8.el100 when deployed with a service that accepts legacy AUTHGSSAPI requests 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:N/UI:N/S:U/C:N/I:N/A:H - 7.5 (HIGH) AV:N - The issue is reachable over network RPC in services that expose the vulnerable legacy AUTHGSSAPI path. AC:L - Once that path is exposed, sending a decodable AUTHGSSAPIINIT request with an unsupported version is straightforward. PR:N - The leak occurs before authentication completes and does not require valid credentials. UI:N - No user interaction is needed. S:U - The impact is contained to the vulnerable service. C:N - No confidentiality impact is demonstrated. I:N - No integrity impact is demonstrated. A:H - Repeated requests can accumulate leaked memory and deny service through memory exhaustion. Impact: Important. Red Hat guidance classifies flaws that allow remote users to cause a denial of service as Important, and this issue permits unauthenticated remote memory exhaustion against an affected network service. The legacy nature of the AUTHGSSAPI path narrows exposure, but the demonstrated consequence is still a direct remote availability loss rather than a merely theoretical source-only defect. Embargo: no Reason: This is an availability-only flaw in a legacy authentication path, the fix is small and low risk, and operators can reduce exposure by restricting access to affected services while a package update is prepared. Acknowledgement: Aisle Research Vulnerability Details: During pre-auth AUTHGSSAPIINIT handling, gssrpcsvcauthgssapi() decodes attacker-controlled input into callarg. Two subsequent error branches return through error: before the only INIT-path xdrfree((xdrproct)xdrauthgssapiinitarg, &callarg); is reached, and the shared error: block frees only creds. As a result, the decoded token buffer can be leaked once per request. c / call is for us, deserialize arguments / memset(&callarg, 0, sizeof(callarg)); if (! svcgetargs(rqst->rqxprt, (xdrproct)xdrauthgssapiinitarg, &callarg)) { PRINTF(("svcauthgssapi: cannot decode args\n")); LOGMISCERR("protocol error in procedure arguments"); ret = AUTHBADCRED; goto error; } ... switch (callarg.version) { ... default: PRINTF(("svcauthgssapi: bad GSSAPIINIT version\n")); LOGMISCERR("unsupported GSSAPIINIT version"); ret = AUTHBADCRED; goto error; } ... if (rqst->rqxprt->xpladdrlen > 0) { bindings.acceptoraddrtype = GSSCAFINET; bindings.acceptoraddress.length = 4; bindings.acceptoraddress.value = &rqst->rqxprt->xpladdr.sinaddr.saddr; } else { LOGMISCERR("cannot get local address"); ret = AUTHFAILED; goto error; } ... / done with call args / xdrfree((xdrproct)xdrauthgssapiinitarg, &callarg); ... error: if (creds.clienthandle.length != 0) { PRINTF(("svcauthgssapi: freeing clienthandle len %d\n", (int) creds.clienthandle.length)); xdrfree((xdrproct)xdrauthgssapicreds, &creds); } PRINTF(("\n")); return ret; The unsupported-version branch is sufficient to trigger the leak and does not depend on the less common xpladdrlen <= 0 case. The available package context also shows server-side acceptance of AUTHGSSAPI in kadmind, so this is not limited to unreachable library code. Transport cleanup does not resolve this case because the relevant cleanup happens only on decode failure, not on later application-auth error exits after callarg has already been allocated. Steps to reproduce: 1. Run a service from krb5-1.21.3-8.el100 that accepts legacy AUTHGSSAPI requests, such as kadmind, with ASAN or RSS monitoring enabled. 2. Send RPC requests with auth flavor AUTHGSSAPI, procedure AUTHGSSAPIINIT, and wrapper fields that allow svcgetargs(..., xdrauthgssapiinitarg, &callarg) to decode successfully, such as creds.version=2, authmsg=true, and an empty clienthandle. 3. Set callarg.version to an unsupported value such as 5, and include a large token so the decoded callarg.token allocation is substantial. 4. Repeat the request and observe monotonic memory growth without a corresponding free for the decoded INIT token. 5. Confirm the request exits through the unsupported-version branch, or the xpladdrlen <= 0 branch, before reaching the sole INIT-path xdrfree((xdrproct)xdrauthgssapiinitarg, &callarg);. Mitigation: Until a fixed package is available, restrict network access to services that accept legacy AUTHGSSAPI to trusted management networks and monitor or rate-limit repeated failing AUTHGSSAPIINIT traffic where possible. If operationally feasible, prefer deployments that do not expose the legacy AUTHGSSAPI path to untrusted clients. Proposed Fix: Free callarg before each early goto error that occurs after successful INIT decode. diff diff --git a/src/lib/rpc/svcauthgssapi.c b/src/lib/rpc/svcauthgssapi.c — a/src/lib/rpc/svcauthgssapi.c +++ b/src/lib/rpc/svcauthgssapi.c @@ -337,6 +337,7 @@ default: PRINTF(("svcauthgssapi: bad GSSAPIINIT version\n")); LOGMISCERR("unsupported GSSAPIINIT version"); + xdrfree((xdrproct)xdrauthgssapiinitarg, &callarg); ret = AUTHBADCRED; goto error; } @@ -361,6 +362,7 @@ } else { LOGMISCERR("cannot get local address"); + xdrfree((xdrproct)xdrauthgssapiinitarg, &callarg); ret = AUTHFAILED; goto error; } ------ This report was generated using AI technology. Always review AI-generated content prior to use

First published (updated )
Severity
7

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: DoS in kadmind via NULL dereference in unauthorized policy logging (logunauth): an authenticated but unauthorized client can send a crafted policy RPC request with a NULL policy name and crash kadmind through strlen(NULL) in the unauthorized logging path. Requirements to exploit: A running and reachable kadmind instance, a valid principal that can issue admin RPC requests but lacks policy-administration rights, and the ability to send a crafted RPC request that encodes the policy name as an XDR nullstring (size=0) instead of relying on normal kadmin CLI validation. Component affected: krb5 kadmind policy RPC handling in src/kadmin/server/serverstubs.c (logunauth(), createpolicy2svc(), deletepolicy2svc(), modifypolicy2svc(), getpolicy2svc()), with NULL policy-name inputs admitted by src/lib/kadm5/kadmrpcxdr.c Version affected: krb5-1.21.3-8.el100 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 vulnerable path is reachable over the network through kadmind RPC requests. AC:L - Exploitation requires only a crafted policy RPC request with a NULL XDR string; no race or unusual environmental condition was established. PR:L - The attacker must authenticate, but does not need policy-administration privileges. UI:N - No user interaction is required. S:U - The crash affects the same kadmind security scope. C:N - No confidentiality impact was established. I:N - No integrity impact was established. A:H - The NULL dereference can terminate kadmind, denying administrative service until it is restarted. Impact: Important. This issue allows a remote authenticated attacker to cause a denial of service in kadmind, which aligns with Red Hat's Important category for flaws that allow remote users to impact availability. It is not Critical because authentication is required and no confidentiality, integrity, or code-execution impact was established. Embargo: no Reason: The available evidence supports an authenticated denial of service in an administrative daemon, with no demonstrated confidentiality or integrity impact and straightforward operational mitigations while a fix is prepared. Acknowledgement: Aisle Research Vulnerability Details: In src/kadmin/server/serverstubs.c, logunauth() calls strlen(target) without first checking whether target is NULL: c static int logunauth( char op, char target, gssbuffert client, gssbuffert server, struct svcreq rqstp) { sizet tlen, clen, slen; char tdots, cdots, sdots; tlen = strlen(target); truncname(&tlen, &tdots); clen = client->length; truncname(&clen, &cdots); slen = server->length; truncname(&slen, &sdots); / okay to cast lengths to int because truncname limits max value / return krb5klogsyslog(LOGNOTICE, ("Unauthorized request: %s, %.s%s, " "client=%.s%s, service=%.s%s, addr=%s"), op, (int)tlen, target, tdots, (int)clen, (char )client->value, cdots, (int)slen, (char )server->value, sdots, clientaddr(rqstp->rqxprt)); } The policy RPC handlers createpolicy2svc(), deletepolicy2svc(), modifypolicy2svc(), and getpolicy2svc() pass request-derived arg->rec.policy or arg->name directly into logunauth() when authorization fails. Those policy-name fields are decoded with xdrnullstring(), and a zero-length XDR string is accepted and decoded to NULL. As a result, an authenticated caller can send a crafted policy request with a NULL policy name, force the unauthorized branch, and reach strlen(NULL) in the logging path. The success-path logging already substitutes "(null)" for NULL names, so the crash is specific to unauthorized-request logging. Steps to reproduce: 1. Run kadmind. 2. Authenticate as a valid principal that can issue admin RPC requests but lacks policy-administration rights. 3. Send one of CREATEPOLICY, DELETEPOLICY, MODIFYPOLICY, or GETPOLICY with the policy name encoded as an XDR nullstring (size=0), so the server decodes the field to NULL. 4. Ensure the request follows the unauthorized branch. 5. logunauth(..., target=NULL, ...) executes strlen(NULL), causing a SIGSEGV and denial of kadmind service. Normal kadmin client-side checks may reject NULL names, so reproduction appears to require a crafted RPC request rather than the stock CLI. Mitigation: Restrict network access to kadmind to trusted administrative hosts and limit which principals can authenticate to the admin RPC service. Where the service is not required, disabling kadmind removes reachability. These measures reduce exposure but do not remove the vulnerable code path from a reachable instance. Proposed Fix: A minimal fix is to make logunauth() handle a NULL target the same way logdone() already does. diff diff --git a/src/kadmin/server/serverstubs.c b/src/kadmin/server/serverstubs.c — a/src/kadmin/server/serverstubs.c +++ b/src/kadmin/server/serverstubs.c @@ -384,6 +384,9 @@ logunauth( sizet tlen, clen, slen; char tdots, cdots, sdots; + if (target == NULL) + target = "(null)"; + tlen = strlen(target); truncname(&tlen, &tdots); ------ This report was generated using AI technology. Always review AI-generated content prior to use

First published (updated )
Severity
6.5
AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: Authenticated DoS via Memory Leak in xdrkrb5tldata Decode Error Path: malformed authenticated kadmind RPC requests with non-null tldata can leak heap allocations on decode failure and eventually exhaust process memory. Requirements to exploit: Network reachability to kadmind, valid credentials for a principal able to establish an authenticated RPCSECGSS session to the kadmin RPC service, and the ability to send a malformed request that decodes kadm5principalentrec with non-null tldata. Component affected: krb5-1.21.3-8.el100, src/lib/kadm5/kadmrpcxdr.c, xdrkrb5tldata() in the kadmind request decode path for kadm5principalentrec.tldata. Version affected: krb5-1.21.3-8.el100 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 vulnerable path is reachable over the network through the kadmind RPC service. AC:L - Exploitation only requires sending malformed tldata that fails decoding after allocation. PR:L - A valid authenticated RPCSECGSS session to kadmind is required; the leak occurs during request decoding rather than after successful completion of the requested administrative operation. UI:N - No user interaction is required once the attacker can send requests. S:U - The impact is confined to the kadmind service boundary. C:N - No confidentiality impact is established by the available evidence. I:N - No integrity impact is established by the available evidence. A:H - Repeated requests can drive unbounded memory growth and deny availability of the long-lived kadmind process. Impact: Important. Red Hat classifies remote denial of service issues as Important when they can readily compromise service availability. This issue allows an authenticated remote user to repeatedly exhaust memory in kadmind through a normal request decode path once a valid session exists. Critical is not appropriate because authentication is required and no code execution, privilege escalation, or broader system compromise is established. Embargo: no Reason: The issue is limited to authenticated availability impact against an administrative service, and operators can reduce exposure by restricting access to kadmind until a fix is available. Acknowledgement: Aisle Research Vulnerability Details: In xdrkrb5tldata(), the XDRDECODE path allocates a new krb5tldata element and decodes its fields before the accumulated list is linked into tldatahead. The affected block is: c case XDRDECODE: tl = NULL; while (1) { if (!xdrbool(xdrs, &more)) return FALSE; if (more == FALSE) break; tl2 = (krb5tldata ) malloc(sizeof(krb5tldata)); if (tl2 == NULL) return FALSE; memset(tl2, 0, sizeof(krb5tldata)); if (!xdrkrb5int16(xdrs, &tl2->tldatatype)) return FALSE; if (!xdrbytes(xdrs, (char )&tl2->tldatacontents, &len, ~0)) return FALSE; tl2->tldatalength = len; tl2->tldatanext = tl; tl = tl2; } tldatahead = tl; break; If xdrbool, xdrkrb5int16, or xdrbytes fails after allocation, the function returns FALSE immediately. At that point, the current tl2 allocation, any tl2->tldatacontents buffer allocated by xdrbytes, and any previously built tl chain are not attached to tldatahead. In the kadmind request path, failed RPC argument decoding is cleaned up through the decoded argument object; because the partially constructed list is never linked into that object, those allocations remain unreachable to normal XDRFREE cleanup and are leaked. The available evidence shows this is reachable with authenticated CREATEPRINCIPAL and MODIFYPRINCIPAL requests that carry non-null rec.tldata. Steps to reproduce: 1. Start kadmind built from krb5-1.21.3-8.el100 with normal RPCSECGSS authentication. 2. Authenticate as any principal able to establish a valid RPCSECGSS session to the kadmin RPC service. 3. Send a CREATEPRINCIPAL or MODIFYPRINCIPAL RPC request containing non-null rec.tldata. 4. In the tldata sequence, set more = TRUE, begin one entry, then truncate or corrupt the stream so decoding fails at xdrkrb5int16 or xdrbytes. 5. Repeat the malformed request and monitor kadmind RSS with ps or /proc/<pid>/status; the process memory grows monotonically across failed decodes. Mitigation: Until a fixed package is available, restrict network access to kadmind to trusted administration hosts, limit which principals can establish authenticated sessions where deployment policy allows, and monitor or restart kadmind if abnormal RSS growth is observed. Disabling kadmind where it is not required removes remote exposure to the vulnerable decode path. Proposed Fix: Route all XDRDECODE failures through a cleanup path that frees the current element and any previously built tldata chain before returning FALSE. diff diff --git a/src/lib/kadm5/kadmrpcxdr.c b/src/lib/kadm5/kadmrpcxdr.c — a/src/lib/kadm5/kadmrpcxdr.c +++ b/src/lib/kadm5/kadmrpcxdr.c @@ -334,27 +334,40 @@ boolt xdrkrb5tldata(XDR xdrs, krb5tldata tldatahead) case XDRDECODE: tl = NULL; + tl = NULL; while (1) { if (!xdrbool(xdrs, &more))

return FALSE; + goto decodefail; if (more == FALSE) break; tl2 = (krb5tldata ) malloc(sizeof(krb5tldata)); if (tl2 == NULL)

return FALSE; + goto decodefail; memset(tl2, 0, sizeof(krb5tldata));

if (!xdrkrb5int16(xdrs, &tl2->tldatatype))

return FALSE;

if (!xdrbytes(xdrs, (char )&tl2->tldatacontents, &len, ~0))

return FALSE; + if (!xdrkrb5int16(xdrs, &tl2->tldatatype)) { + free(tl2); + goto decodefail; + } + if (!xdrbytes(xdrs, (char )&tl2->tldatacontents, &len, ~0)) { + free(tl2->tldatacontents); + free(tl2); + goto decodefail; + } tl2->tldatalength = len;

tl2->tldatanext = tl; tl = tl2; } tldatahead = tl; break; + +decodefail: + while (tl != NULL) { + tl2 = tl->tldatanext; + free(tl->tldatacontents); + free(tl); + tl = tl2; + } + return FALSE; } ------ This report was generated using AI technology. Always review AI-generated content prior to use

1 / 2
Source: Red Hat
First published (updated )
Severity
6.5
Null Pointer Dereference
AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: DoS in kadmind via NULL dereference in unauthorized policy logging (logunauth): an authenticated but unauthorized client can send a crafted policy RPC request with a NULL policy name and crash kadmind through strlen(NULL) in the unauthorized logging path. Requirements to exploit: A running and reachable kadmind instance, a valid principal that can issue admin RPC requests but lacks policy-administration rights, and the ability to send a crafted RPC request that encodes the policy name as an XDR nullstring (size=0) instead of relying on normal kadmin CLI validation. Component affected: krb5 kadmind policy RPC handling in src/kadmin/server/serverstubs.c (logunauth(), createpolicy2svc(), deletepolicy2svc(), modifypolicy2svc(), getpolicy2svc()), with NULL policy-name inputs admitted by src/lib/kadm5/kadmrpcxdr.c Version affected: krb5-1.21.3-8.el100 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 vulnerable path is reachable over the network through kadmind RPC requests. AC:L - Exploitation requires only a crafted policy RPC request with a NULL XDR string; no race or unusual environmental condition was established. PR:L - The attacker must authenticate, but does not need policy-administration privileges. UI:N - No user interaction is required. S:U - The crash affects the same kadmind security scope. C:N - No confidentiality impact was established. I:N - No integrity impact was established. A:H - The NULL dereference can terminate kadmind, denying administrative service until it is restarted. Impact: Important. This issue allows a remote authenticated attacker to cause a denial of service in kadmind, which aligns with Red Hat's Important category for flaws that allow remote users to impact availability. It is not Critical because authentication is required and no confidentiality, integrity, or code-execution impact was established. Embargo: no Reason: The available evidence supports an authenticated denial of service in an administrative daemon, with no demonstrated confidentiality or integrity impact and straightforward operational mitigations while a fix is prepared. Acknowledgement: Aisle Research Vulnerability Details: In src/kadmin/server/serverstubs.c, logunauth() calls strlen(target) without first checking whether target is NULL: c static int logunauth( char op, char target, gssbuffert client, gssbuffert server, struct svcreq rqstp) { sizet tlen, clen, slen; char tdots, cdots, sdots; tlen = strlen(target); truncname(&tlen, &tdots); clen = client->length; truncname(&clen, &cdots); slen = server->length; truncname(&slen, &sdots); / okay to cast lengths to int because truncname limits max value / return krb5klogsyslog(LOGNOTICE, ("Unauthorized request: %s, %.s%s, " "client=%.s%s, service=%.s%s, addr=%s"), op, (int)tlen, target, tdots, (int)clen, (char )client->value, cdots, (int)slen, (char )server->value, sdots, clientaddr(rqstp->rqxprt)); } The policy RPC handlers createpolicy2svc(), deletepolicy2svc(), modifypolicy2svc(), and getpolicy2svc() pass request-derived arg->rec.policy or arg->name directly into logunauth() when authorization fails. Those policy-name fields are decoded with xdrnullstring(), and a zero-length XDR string is accepted and decoded to NULL. As a result, an authenticated caller can send a crafted policy request with a NULL policy name, force the unauthorized branch, and reach strlen(NULL) in the logging path. The success-path logging already substitutes "(null)" for NULL names, so the crash is specific to unauthorized-request logging. Steps to reproduce: 1. Run kadmind. 2. Authenticate as a valid principal that can issue admin RPC requests but lacks policy-administration rights. 3. Send one of CREATEPOLICY, DELETEPOLICY, MODIFYPOLICY, or GETPOLICY with the policy name encoded as an XDR nullstring (size=0), so the server decodes the field to NULL. 4. Ensure the request follows the unauthorized branch. 5. logunauth(..., target=NULL, ...) executes strlen(NULL), causing a SIGSEGV and denial of kadmind service. Normal kadmin client-side checks may reject NULL names, so reproduction appears to require a crafted RPC request rather than the stock CLI. Mitigation: Restrict network access to kadmind to trusted administrative hosts and limit which principals can authenticate to the admin RPC service. Where the service is not required, disabling kadmind removes reachability. These measures reduce exposure but do not remove the vulnerable code path from a reachable instance. Proposed Fix: A minimal fix is to make logunauth() handle a NULL target the same way logdone() already does. diff diff --git a/src/kadmin/server/serverstubs.c b/src/kadmin/server/serverstubs.c — a/src/kadmin/server/serverstubs.c +++ b/src/kadmin/server/serverstubs.c @@ -384,6 +384,9 @@ logunauth( sizet tlen, clen, slen; char tdots, cdots, sdots; + if (target == NULL) + target = "(null)"; + tlen = strlen(target); truncname(&tlen, &tdots); ------ This report was generated using AI technology. Always review AI-generated content prior to use

1 / 2
Source: Red Hat
First published (updated )
Severity
6.5
AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: Authenticated Memory Exhaustion and Leak in RPCSECGSS Unwrapping (xdrrpcgssunwrapdata): authenticated RPCSECGSS 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 RPCSECGSS 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/authgssprot.c:xdrrpcgssunwrapdata via xdrrpcgssbuf, with the allocation behavior in src/lib/rpc/xdr.c:xdrbytes Version affected: krb5-1.21.3-8.el100 when deployed with a service that accepts authenticated RPCSECGSSDATA 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 RPCSECGSS 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 RPCSECGSS 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 RPCSECGSS 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 RPCSECGSS credentials and exposure of a vulnerable RPCSECGSS service, and the demonstrated impact is denial of service rather than code execution or privilege escalation. Acknowledgement: Aisle Research Vulnerability Details: xdrrpcgssunwrapdata decodes attacker-controlled wrapped buffers with maxsize = (unsigned int)-1 for both integrity and privacy services. That value is then passed into xdrbytes, which allocates memory directly from the wire length before MIC verification or unwrap validation completes. c if (svc == RPCSECGSSSVCINTEGRITY) { / Decode databodyinteg. / if (!xdrrpcgssbuf(xdrs, &databuf, (unsigned int)-1)) { logdebug("xdr decode databodyinteg failed"); return (FALSE); } / Decode checksum. / if (!xdrrpcgssbuf(xdrs, &wrapbuf, (unsigned int)-1)) { gssreleasebuffer(&minstat, &databuf); logdebug("xdr decode checksum failed"); return (FALSE); } / Verify checksum and QOP. / majstat = gssverifymic(&minstat, ctx, &databuf, &wrapbuf, &qopstate); free(wrapbuf.value); if (majstat != GSSSCOMPLETE || qopstate != qop) { gssreleasebuffer(&minstat, &databuf); logstatus("gssverifymic", majstat, minstat); return (FALSE); } } else if (svc == RPCSECGSSSVCPRIVACY) { / Decode databodypriv. / if (!xdrrpcgssbuf(xdrs, &wrapbuf, (unsigned int)-1)) { logdebug("xdr decode databodypriv failed"); return (FALSE); } c if (! xdruint(xdrs, sizep)) { return (FALSE); } nodesize = sizep; if ((nodesize > maxsize) && (xdrs->xop != XDRFREE)) { return (FALSE); } / now deal with the actual bytes / switch (xdrs->xop) {

case XDRDECODE: if (nodesize == 0) { return (TRUE); } if (sp == NULL) { cpp = sp = (char )memalloc(nodesize); } Because maxsize is effectively UINTMAX in this call path, the nodesize > maxsize check does not provide a practical bound. The allocation happens before gssverifymic() or gssunwrap(), 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 RPCSECGSS enabled over TCP, for example an administration service using the GSSRPC server path. 2. Establish a valid RPCSECGSS context as an authenticated client. 3. Send an RPCSECGSSDATA request with gcproc = RPCSECGSSDATA and gcsvc = RPCSECGSSSVCINTEGRITY or RPCSECGSSSVCPRIVACY. 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 RPCSECGSS 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/authgssprot.c b/src/lib/rpc/authgssprot.c — a/src/lib/rpc/authgssprot.c +++ b/src/lib/rpc/authgssprot.c @@ -46,6 +46,9 @@ #include <gssapi/gssapi.h> #endif +/ Upper bound for decoded wrapped RPCSECGSS payloads. / +#define RPCSECGSSMAXUNWRAP (16U 1024U 1024U) + boolt xdrrpcgssbuf(XDR xdrs, gssbuffert buf, uint maxsize) { @@ -202,13 +205,18 @@ xdrrpcgssunwrapdata(XDR xdrs, xdrproct xdrfunc, caddrt xdrptr, if (svc == RPCSECGSSSVCINTEGRITY) { / Decode databodyinteg. / - if (!xdrrpcgssbuf(xdrs, &databuf, (unsigned int)-1)) { + if (!xdrrpcgssbuf(xdrs, &databuf, RPCSECGSSMAXUNWRAP)) { logdebug("xdr decode databodyinteg failed"); return (FALSE); } / Decode checksum. / - if (!xdrrpcgssbuf(xdrs, &wrapbuf, (unsigned int)-1)) { + if (!xdrrpcgssbuf(xdrs, &wrapbuf, RPCSECGSSMAXUNWRAP)) { gssreleasebuffer(&minstat, &databuf); + if (wrapbuf.value != NULL) + free(wrapbuf.value); logdebug("xdr decode checksum failed"); return (FALSE); } @@ -225,7 +233,10 @@ xdrrpcgssunwrapdata(XDR xdrs, xdrproct xdrfunc, caddrt xdrptr, } else if (svc == RPCSECGSSSVCPRIVACY) { / Decode databodypriv. / - if (!xdrrpcgssbuf(xdrs, &wrapbuf, (unsigned int)-1)) { + if (!xdrrpcgssbuf(xdrs, &wrapbuf, RPCSECGSSMAXUNWRAP)) { + if (wrapbuf.value != NULL) + free(wrapbuf.value); logdebug("xdr decode databodypriv failed"); return (FALSE); } ------ This report was generated using AI technology. Always review AI-generated content prior to use

1 / 2
Source: Red Hat
First published (updated )
Severity
5.3
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: Pre-auth Memory Leak in RPCSECGSS Credential Decode Failure Path (gssrpcsvcauthgss): malformed unauthenticated RPCSECGSS credentials can leak gcctx allocations on decode failure, allowing gradual memory-exhaustion denial of service. Requirements to exploit: Network reachability to a service from krb5-1.21.3-8.el100 that parses RPCSECGSS credentials before authentication, plus the ability to send repeated malformed RPC requests with a truncated embedded gcctx buffer. No prior authentication or user interaction is required. Component affected: krb5-1.21.3-8.el100, src/lib/rpc/svcauthgss.c, gssrpcsvcauthgss (with the leaking allocation originating from xdrrpcgsscred() via xdrrpcgssbuf() / xdrbytes()) Version affected: krb5-1.21.3-8.el100 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:N/UI:N/S:U/C:N/I:N/A:L - 5.3 (MEDIUM) AV:N - The affected code parses attacker-controlled RPC credential data over the network. AC:L - The failure condition is induced with a malformed but simple truncated credential blob. PR:N - The leak occurs in the pre-authentication credential decode path. UI:N - No user interaction is required. S:U - The impact is limited to the targeted service process. C:N - The available evidence does not show unauthorized data disclosure. I:N - The available evidence does not show data modification or code execution. A:L - Each request leaks only a bounded amount of memory (MAXAUTHBYTES), but repeated requests can accumulate enough loss to degrade or eventually exhaust the service. Impact: Important. Red Hat classifies flaws that allow remote users to cause denial of service as Important, and this issue is reachable before authentication where an exposed RPCSECGSS service path exists. The practical effect established here is gradual availability loss rather than immediate crash or system compromise, because the leak is bounded per request and requires repetition. Embargo: no Reason: The demonstrated impact is availability-only, the leak is gradual, and straightforward mitigations exist by restricting network access to affected RPCSECGSS-enabled administrative services while a fix is prepared. Acknowledgement: Aisle Research Vulnerability Details: In gssrpcsvcauthgss(), a decode failure returns immediately instead of using the existing freegc: cleanup path: c if (!xdrrpcgsscred(&xdrs, gc)) { logdebug("xdrrpcgsscred() failed"); XDRDESTROY(&xdrs); return (AUTHBADCRED); } ... freegc: xdrfree((xdrproct)xdrrpcgsscred, gc); logdebug("returning %d from svcauthgss()", retstat); return (retstat); The decoded gcctx field is populated through xdrrpcgssbuf() and xdrbytes(). On XDRDECODE, xdrbytes() allocates the buffer before it attempts to read the declared opaque bytes. If the embedded RPCSECGSS credential advertises a non-zero gcctx length but truncates the remaining credential bytes, the opaque read can fail after allocation. Because the function returns before xdrfree((xdrproct)xdrrpcgsscred, gc) is reached, that nested allocation is not released on the failing request. The available material further supports that this parser is selected from the server authentication dispatch when cbcred.oaflavor is RPCSECGSS. The resulting leak is bounded per request by the credential-size checks, but repeated malformed unauthenticated requests can cause monotonic memory growth over time. The evidence supports this for deployments that expose an RPCSECGSS-enabled service path, including in-tree administrative paths such as kadmind or iprop; it does not establish that every deployment of the SRPM exposes those paths. Steps to reproduce: 1. Reach a server path built from krb5-1.21.3-8.el100 that accepts RPCSECGSS credentials before authentication. 2. Send an RPC call with cbcred.oaflavor = RPCSECGSS. 3. Keep the outer credential blob within the accepted MAXAUTHBYTES limit so decoding proceeds into the embedded RPCSECGSS credential. 4. Inside the embedded credential, set gcctx to a non-zero declared length but truncate the remaining bytes so allocation occurs and the subsequent opaque-byte read fails. 5. Observe an authentication failure associated with AUTHBADCRED while the service retains the allocation from the failed decode path. 6. Repeat the malformed request and monitor service memory growth over time. Mitigation: Restrict network access to RPCSECGSS-enabled administrative services to trusted clients until a fix is available. Where feasible, do not expose kadmind/iprop-related RPC endpoints to untrusted networks, and apply rate limiting or connection controls to reduce the effect of repeated malformed requests. Proposed Fix: Route the decode-failure path through the existing freegc: cleanup so partially decoded RPCSECGSS credentials are always released. diff diff --git a/krb5-1.21.3/src/lib/rpc/svcauthgss.c b/krb5-1.21.3/src/lib/rpc/svcauthgss.c index <old>..<new> 100644 — a/krb5-1.21.3/src/lib/rpc/svcauthgss.c +++ b/krb5-1.21.3/src/lib/rpc/svcauthgss.c @@ -434,10 +434,12 @@ gssrpcsvcauthgss(struct svcreq rqst, struct rpcmsg msg, rqst->rqcred.oalength, XDRDECODE); logdebug("xdrmemcreate() returned"); if (!xdrrpcgsscred(&xdrs, gc)) { logdebug("xdrrpcgsscred() failed"); XDRDESTROY(&xdrs); return (AUTHBADCRED); + retstat = AUTHBADCRED; + goto freegc; } XDRDESTROY(&xdrs);

An equivalent fix is to call xdrfree((xdrproct)xdrrpcgsscred, gc) immediately before returning AUTHBADCRED. ------ This report was generated using AI technology. Always review AI-generated content prior to use

1 / 2
Source: Red Hat
First published (updated )
Severity
5.3
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: KDB keytab memory leak in krb5ktkdbgetentry() error paths (remote DoS): decrypted key material is left allocated when krb5ktkdbgetentry() takes a later error path, allowing repeated remote requests against exposed KDB:-backed service paths to accumulate leaked memory and degrade availability. Requirements to exploit: Network reachability to a deployment of krb5-1.21.3-8.el100 that exposes a service path using the KDB: keytab, the ability to send repeated crafted requests that make krb5ktkdbgetentry() fail after krb5dbedecryptkeydata() succeeds, and enough request volume to accumulate leaked heap memory. Based on the observed request flow, prior authentication is not required to reach the lookup path. Component affected: krb5-1.21.3-8.el100, src/lib/kdb/keytab.c, krb5ktkdbgetentry(); reachable through KDB:-backed administrative/password-change request handling. Version affected: krb5-1.21.3-8.el100 in builds that include the non-LEANCLIENT KDB: keytab code and expose a network-facing service path using KDB: 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:N/UI:N/S:U/C:N/I:N/A:L - 5.3 (MEDIUM) AV:N - The affected lookup path can be reached over the network through exposed KDB:-backed administrative/password-change services. AC:L - No race or special attack condition is established beyond reaching the affected service and causing a post-decrypt error. PR:N - The request reaches keytab lookup before the client is authenticated. UI:N - No user interaction is required. S:U - The impact is limited to the affected service process. C:N - No confidentiality impact is established. I:N - No integrity impact is established. A:L - Repeated requests can leak memory and degrade or eventually interrupt service availability, but the established effect is incremental resource exhaustion. Impact: Important. Red Hat classifies flaws that allow remote users to cause a denial of service as Important. Here, the established impact is remote availability loss against an exposed network service path without prior authentication. This is not Critical because no code execution, confidentiality loss, or broader system compromise is established. The issue is deployment-dependent on use of KDB:-backed service paths, but where those paths are exposed it fits the Important category more closely than Moderate. Embargo: no Reason: The established impact is availability degradation rather than code execution or data compromise, and exposure can be reduced operationally by restricting access to the affected services while a fix is prepared. Acknowledgement: Aisle Research Vulnerability Details: In src/lib/kdb/keytab.c, krb5ktkdbgetentry() decrypts the selected KDB key into entry->key. If a later check fails, execution jumps to error: and returns without releasing that key material: c kerror = krb5dbedecryptkeydata(context, NULL, keydata, &entry->key, NULL); if (kerror) goto error; if (enctype > 0) { kerror = krb5cenctypecompare(context, enctype, entry->key.enctype, &similar); if (kerror) goto error; if (!similar) { kerror = KRB5KDBNOPERMITTEDKEY; goto error; } } / Coerce the enctype of the output keyblock in case we got an

inexact match on the enctype. / entry->key.enctype = enctype;

kerror = krb5copyprincipal(context, principal, &entry->principal); if (kerror) goto error; / Close database / error: krb5dbfreeprincipal(context, dbentry); / krb5dbclosedatabase(context); / return(kerror); The most straightforward post-decrypt failure shown by the code is a non-similar enctype comparison leading to KRB5KDBNOPERMITTEDKEY; an allocation failure in krb5copyprincipal() would have the same leak outcome. The generic keytab dispatch path returns provider errors without reclaiming partially initialized entry state, so once this function returns an error after populating entry->key, the allocation becomes unreachable. A concrete network-facing use of this path exists where the administrative/password-change service resolves KDB: and authenticates incoming requests against it. Based on the available technical evidence, the remote availability impact is well supported for deployments exposing those KDB:-backed service paths. This report does not rely on a broader claim that every Kerberos service path in the package is affected in the same way. Steps to reproduce: 1. Deploy krb5-1.21.3-8.el100 with its database initialized and a network-reachable administrative or password-change service path that uses KDB:. 2. Send repeated AP-REQ requests to that service so it performs krb5ktgetentry() and then krb5ktkdbgetentry() for the service principal. 3. Craft requests so lookup reaches a post-decrypt error after krb5dbedecryptkeydata() succeeds. A non-similar enctype causing KRB5KDBNOPERMITTEDKEY is one concrete condition visible in the code. 4. Observe the daemon's memory usage over many failing requests. Resident memory should grow while the requests continue to fail. 5. Apply the patch below, rebuild, and repeat the same request pattern. Memory growth from this error path should no longer accumulate. Mitigation: Until a fix is shipped, restrict network access to the administrative/password-change interfaces that use KDB:, disable those services if they are not required, and apply rate limiting or ACLs to untrusted sources. If repeated failures have already caused memory growth, restarting the affected daemon recovers the leaked heap state. Proposed Fix: Track whether entry->key has been populated and free it on error before returning. diff diff --git a/src/lib/kdb/keytab.c b/src/lib/kdb/keytab.c — a/src/lib/kdb/keytab.c +++ b/src/lib/kdb/keytab.c @@ -123,6 +123,7 @@ krb5ktkdbgetentry(krb5context incontext, krb5keytab id, krb5keydata keydata; krb5dbentry dbentry; int xrealmtgt; + krb5boolean keypopulated = FALSE; krb5boolean similar; @@ -166,8 +167,10 @@ krb5ktkdbgetentry(krb5context incontext, krb5keytab id, kerror = krb5dbedecryptkeydata(context, NULL, keydata, &entry->key, NULL); if (kerror) goto error; + keypopulated = TRUE; @@ -193,6 +196,8 @@ krb5ktkdbgetentry(krb5context incontext, krb5keytab id, error: + if (kerror && keypopulated) + krb5freekeyblockcontents(context, &entry->key); krb5dbfreeprincipal(context, dbentry); / krb5dbclosedatabase(context); / return(kerror); ------ This report was generated using AI technology. Always review AI-generated content prior to use

1 / 2
Source: Red Hat
First published (updated )
Severity
4

AIONLYREPORT package: krb5-1.21.3-8.el100 ------ Summary: Unbounded Memory Leak in clnttcpcall on XID Mismatch (plus retry leak on AUTHREFRESH): a malicious RPC peer or on-path attacker can cause unbounded client-side memory growth and denial of service by sending accepted TCP RPC replies with mismatched transaction IDs and non-empty verifiers. Requirements to exploit: An application using the TCP RPC client path in krb5-1.21.3-8.el100 must issue a call through clnttcpcall, and the attacker must be able to act as the RPC server or inject syntactically valid reply records on the connection before a matching reply is processed. Component affected: krb5-1.21.3-8.el100, src/lib/rpc/clnttcp.c, clnttcpcall (with verifier allocation reached through xdropaqueauth() and xdrbytes()) Version affected: krb5-1.21.3-8.el100 when the TCP RPC client path in clnttcpcall is used 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:N/UI:N/S:U/C:N/I:N/A:H - 7.5 (HIGH) AV:N - A malicious RPC peer, or an attacker able to inject replies on the network path, can trigger the flaw remotely. AC:L - The attack requires only syntactically valid REPLY messages with a mismatched rmxid and a non-empty verifier. PR:N - No privileges on the client are required. UI:N - No additional user interaction is required once the vulnerable client performs the RPC call. S:U - The impact is confined to the client process using the affected library path. C:N - No confidentiality impact is established by the available evidence. I:N - No integrity impact is established by the available evidence. A:H - Each mismatched accepted reply can leak up to MAXAUTHBYTES (400) and the mismatch loop is unbounded for the duration of the call, allowing sustained memory growth and possible process termination. Impact: Moderate. Red Hat classifies remote denial-of-service issues as Important when they are easy and broadly exploitable, but this case is narrower: it affects a specific client-side RPC path, requires an attacker-controlled or intercepted peer, and the demonstrated consequence is denial of service of the consuming client process only. The available evidence does not establish confidentiality, integrity, or broader system compromise. Embargo: no Reason: This is an availability-only, client-side issue that requires a malicious RPC server or an on-path attacker while the affected TCP RPC client path is in use; the current evidence does not show broad compromise or wormable behavior. Acknowledgement: Aisle Research Vulnerability Details: In clnttcpcall, reply headers are decoded in a loop until replymsg.rmxid == xid. For each iteration, replymsg.acptedrply.arverf is reset to gssrpcnullauth before xdrreplymsg() decodes the reply. When a syntactically valid accepted reply carries a non-matching XID, the loop continues without freeing the verifier buffer that may have been allocated during decode. c while (TRUE) { replymsg.acptedrply.arverf = gssrpcnullauth; replymsg.acptedrply.arresults.where = NULL; replymsg.acptedrply.arresults.proc = xdrvoid; if (! xdrrecskiprecord(xdrs)) return (ct->cterror.restatus); / now decode and validate the response header / if (! xdrreplymsg(xdrs, &replymsg)) { / Free some stuff allocated by xdrreplymsg() to avoid leaks, since it may allocate memory from partially successful decodes. / enum xdrop op = xdrs->xop; xdrs->xop = XDRFREE; xdrreplymsg(xdrs, &replymsg); xdrs->xop = op; if (ct->cterror.restatus == RPCSUCCESS) continue; return (ct->cterror.restatus); } if (replymsg.rmxid == xid) break; }

The final verifier cleanup runs only after the loop exits, and the retry path can also bypass that cleanup: c else { / maybe our credentials need to be refreshed ... / if (refreshes-- && AUTHREFRESH(h->clauth, &replymsg)) goto callagain; } / free verifier ... / if ((replymsg.rmreply.rpstat == MSGACCEPTED) && (replymsg.acptedrply.arverf.oabase != NULL)) { xdrs->xop = XDRFREE; (void)xdropaqueauth(xdrs, &(replymsg.acptedrply.arverf)); } xdropaqueauth() decodes arverf through xdrbytes(), which allocates oabase on decode and releases it only under XDRFREE. On an XID mismatch, the next loop iteration overwrites arverf before that free occurs, so the previous pointer is lost. A second leak exists when AUTHREFRESH() succeeds and jumps to callagain before verifier cleanup. The retry-path leak is bounded by the refresh count and is secondary; the main issue is the unbounded mismatch loop. The available evidence supports availability impact only. Steps to reproduce: 1. Build with ASan, or run under Valgrind, and exercise any client path that uses clnttcpcall. 2. Connect the client to a controlled TCP RPC server, or position an on-path interceptor, that repeatedly sends syntactically valid REPLY records with rmdirection = REPLY, rpstat = MSGACCEPTED, arverf.oalength > 0 (up to MAXAUTHBYTES), and rmxid != client xid. 3. Keep sending mismatched replies while the client waits for the legitimate response. 4. Observe monotonic memory growth in the client process through RSS, ASan, or Valgrind. 5. Optionally, return replies that trigger an auth error followed by a successful AUTHREFRESH() to reproduce the retry-path leak. Mitigation: No complete runtime mitigation is established in the package. Exposure can be reduced by limiting this TCP RPC client path to trusted servers and protected networks, and by using conservative RPC timeouts so a waiting call cannot be held open indefinitely. These measures reduce exposure but do not remove the underlying leak. Proposed Fix: Free the verifier for non-matching accepted replies before the next decode, and free it before retrying callagain on successful AUTHREFRESH(). diff diff --git a/src/lib/rpc/clnttcp.c b/src/lib/rpc/clnttcp.c — a/src/lib/rpc/clnttcp.c +++ b/src/lib/rpc/clnttcp.c @@ -320,6 +320,15 @@ clnttcpcall(CLIENT h, rpcproct proc, xdrproct xdrargs, void argsptr, if (replymsg.rmxid == xid) break; + / Free verifier from non-matching replies before next decode. / + if ((replymsg.rmreply.rpstat == MSGACCEPTED) && + (replymsg.acptedrply.arverf.oabase != NULL)) { + enum xdrop op = xdrs->xop; + xdrs->xop = XDRFREE; + (void)xdropaqueauth(xdrs, &(replymsg.acptedrply.arverf)); + xdrs->xop = op; + } } @@ -340,8 +349,18 @@ clnttcpcall(CLIENT h, rpcproct proc, xdrproct xdrargs, void argsptr, else { / maybe our credentials need to be refreshed ... / if (refreshes- && AUTHREFRESH(h->clauth, &replymsg)) + if (refreshes-- && AUTHREFRESH(h->clauth, &replymsg)) { + / Free verifier before retrying callagain. / + if ((replymsg.rmreply.rpstat == MSGACCEPTED) && + (replymsg.acptedrply.arverf.oabase != NULL)) { + enum xdrop op = xdrs->xop; + xdrs->xop = XDRFREE; + (void)xdropaqueauth(xdrs, + &(replymsg.acptedrply.arverf)); + xdrs->xop = op; + } goto callagain; + } } ------ This report was generated using AI technology. Always review AI-generated content prior to use

First published (updated )

Red Hat Hardened Images RPMs Security Update

Remedy

For details on how to apply this update, which includes the changes described in this advisory, refer to:<br><a href="https://images.redhat.com/" target="_blank">https://images.redhat.com/</a>
First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203