Bug 2479231 (CVE-2026-119079)
| Summary: | CVE-2026-119079 krb5: MIT krb5 KDC unauthenticated CPU DoS via quadratic ASN.1 SEQUENCE OF decoding | ||
|---|---|---|---|
| Product: | [Other] Security Response | Reporter: | OSIDB Bzimport <bzimport> |
| Component: | vulnerability | Assignee: | Product Security DevOps Team <prodsec-dev> |
| Status: | NEW --- | QA Contact: | |
| Severity: | high | Docs Contact: | |
| Priority: | high | ||
| Version: | unspecified | CC: | abokovoy, ftrivino, jrische, rhel-process-autobot, security-response-team, watson-tool-maintainers |
| Target Milestone: | --- | Keywords: | Security |
| Target Release: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | --- | |
| Doc Text: |
decode_sequence_of() in lib/krb5/asn.1/asn1_encode.c in MIT Kerberos 5 (aka krb5) 1.11 and later grows the decoded element array one entry at a time, which allows remote attackers to cause a denial of service (CPU consumption in the KDC) by sending an unauthenticated AS-REQ or TGS-REQ with a large number of elements in a SEQUENCE OF field over TCP.
|
Story Points: | --- |
| Clone Of: | Environment: | ||
| Last Closed: | Type: | --- | |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
| Bug Depends On: | 2569219 | ||
| Bug Blocks: | |||
| Deadline: | 2026-11-09 | ||
Tracker filed for rhel-10.3: https://issues.redhat.com/browse/RHEL-189015 |
AI_ONLY_REPORT package: krb5-1.21.3-8.el10_0 ------ Summary: Algorithmic complexity DoS in ASN.1 `decode_sequence_of()` (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/asn1_encode.c` in `decode_sequence_of()`, reachable from `src/kdc/dispatch.c` during `decode_krb5_as_req()` and `decode_krb5_tgs_req()`. One practical trigger is `PrincipalName.name-string` in `src/lib/krb5/asn.1/asn1_k_encode.c`. Version affected: `krb5-1.21.3-8.el10_0` 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: `decode_sequence_of()` grows the destination array by one element per loop iteration: ```c /* src/lib/krb5/asn.1/asn1_encode.c */ while (len > 0) { ... newseq = realloc(seq, (count + 1) * elemtype->size); if (newseq == NULL) { ret = ENOMEM; goto error; } seq = newseq; ... ret = decode_atype(&t, contents, clen, elemtype, elem); ... count++; } ``` The KDC decodes AS-REQ and TGS-REQ messages before authentication: ```c /* src/kdc/dispatch.c */ if (krb5_is_tgs_req(pkt)) retval = decode_krb5_tgs_req(pkt, &req); else if (krb5_is_as_req(pkt)) retval = decode_krb5_as_req(pkt, &req); ``` One practical trigger is `PrincipalName.name-string`, which is defined as a counted `SEQUENCE OF GeneralString`: ```c /* src/lib/krb5/asn.1/asn1_k_encode.c */ DEFCNFIELD(princname_1, krb5_principal_data, data, length, 1, cseqof_gstring_data); ``` 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.el10_0` 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 `decode_sequence_of()` 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/asn1_encode.c +++ b/src/lib/krb5/asn.1/asn1_encode.c @@ static krb5_error_code decode_sequence_of(const uint8_t *asn1, size_t len, const struct atype_info *elemtype, void **seq_out, size_t *count_out) { krb5_error_code ret; void *seq = NULL, *elem, *newseq; const uint8_t *contents; size_t clen, count = 0; + size_t 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 > SIZE_MAX / elemtype->size) { + ret = ASN1_OVERFLOW; + 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 = decode_atype(&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; + } *seq_out = seq; *count_out = count; return 0; ``` ------ This report was generated using AI technology. Always review AI-generated content prior to use