Fedora Account System
Red Hat Associate
Red Hat Customer
AI_ONLY_REPORT package: libtirpc-1.3.7-2.1.hum1 ------ Summary: Unbounded pmaplist decoding can cause memory exhaustion (DoS): attacker-controlled `PMAPPROC_DUMP` replies can drive unbounded decode-time allocation in `xdr_pmaplist()` and exhaust memory or CPU in the client process. Requirements to exploit: An attacker must be able to make a libtirpc consumer call `pmap_getmaps()` against an attacker-controlled host, or otherwise supply the `PMAPPROC_DUMP` response on that path. No authentication or post-request user interaction is required, but the vulnerable client-side portmapper path must be used by the consuming application. Component affected: `libtirpc-1.3.7-2.1.hum1` portmapper/XDR decode path in `src/pmap_prot2.c` (`xdr_pmaplist()`), reachable from `src/pmap_getmaps.c` (`pmap_getmaps()`) Version affected: `libtirpc-1.3.7-2.1.hum1`, when the `pmap_getmaps()` / `PMAPPROC_DUMP` client decode path is exercised 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:H/PR:N/UI:N/S:U/C:N/I:N/A:H - 5.9 (MEDIUM) AV:N - The malicious `PMAPPROC_DUMP` response is delivered over the network to a client using `pmap_getmaps()`. AC:H - Exploitation depends on the victim using this specific client path against an attacker-controlled or spoofed endpoint; once that precondition holds, the payload is straightforward. PR:N - No authentication is required. UI:N - No additional user interaction is required after the vulnerable request is made. S:U - The impact is limited to the vulnerable client process and its resources. C:N - No confidentiality impact is established by the available evidence. I:N - No integrity impact is established by the available evidence. A:H - A long attacker-controlled list can consume substantial memory and CPU, causing the client to hang, fail allocation, or be terminated. Impact: Moderate. This is a real availability issue, but the available evidence supports a usage-dependent client-side path rather than a broadly exposed server path in the package itself. Under Red Hat's severity guidance, that makes the issue less broadly exploitable than the typical remote DoS cases rated Important, and there is no evidence of confidentiality, integrity, or system-compromise impact. Embargo: no Reason: This is an availability-only flaw in a client-side, usage-dependent path with straightforward short-term mitigations, so immediate public handling appears appropriate. Acknowledgement: Aisle Research Vulnerability Details: `pmap_getmaps()` uses `xdr_pmaplist()` to decode `PMAPPROC_DUMP` replies. In `xdr_pmaplist()`, loop termination depends entirely on the decoded `more_elements` value, and no maximum node count or byte budget is enforced: ```c for (; { more_elements = (bool_t)(*rp != NULL); if (! xdr_bool(xdrs, &more_elements)) return (FALSE); if (! more_elements) return (TRUE); if (! xdr_reference(xdrs, (caddr_t *)rp, (u_int)sizeof(struct pmaplist), (xdrproc_t)xdr_pmap)) return (FALSE); rp = (freeing) ? next : &((*rp)->pml_next); } ``` During `XDR_DECODE`, `xdr_reference()` allocates a new `struct pmaplist` node whenever the pointer is `NULL`: ```c case XDR_DECODE: *pp = loc = (caddr_t) mem_alloc(size); if (loc == NULL) { warnx("xdr_reference: out of memory"); return (FALSE); } memset(loc, 0, size); break; ``` This makes both allocation count and decode work peer-controlled. A responder that keeps sending `more_elements=TRUE` with additional `struct pmap` records can force repeated allocations until the client slows significantly, fails allocation, or is killed for resource exhaustion. The available transport code does not show a total decode budget in this path; the receive timeout is applied per read/poll cycle, so continued input can continue to drive work. Steps to reproduce: 1. Build or use a libtirpc consumer with the portmapper client path enabled and create a small client that calls `pmap_getmaps()` against a host you control. 2. Run a malicious or mock rpcbind/portmapper service on TCP/111 that returns a valid `PMAPPROC_DUMP` reply body containing many repetitions of `bool TRUE` followed by one `struct pmap` record, with a final `bool FALSE` only after a very long list or not until resource exhaustion is reached. 3. Observe client memory and CPU consumption while the reply is decoded through `xdr_pmaplist()`. 4. Increase the number of returned elements; the client eventually becomes slow, fails allocation, or is terminated by the OOM killer. 5. As a validation step, add a local decode cap and confirm the same payload is rejected quickly. Mitigation: Until a fix is available, avoid calling `pmap_getmaps()` against untrusted or attacker-influenced endpoints. If this functionality is required, add a local maximum node or allocation budget for `xdr_pmaplist()` decoding, or isolate the caller so failure only affects a constrained helper process. Proposed Fix: Add an explicit decode-time limit for the number of `pmaplist` nodes accepted by `xdr_pmaplist()`, and fail decoding once the limit is exceeded. ```diff diff --git a/src/pmap_prot2.c b/src/pmap_prot2.c — a/src/pmap_prot2.c +++ b/src/pmap_prot2.c @@ -38,6 +38,10 @@ #include <rpc/xdr.h> #include <rpc/pmap_prot.h> +#ifndef PMAPLIST_DECODE_MAX_NODES +#define PMAPLIST_DECODE_MAX_NODES 1024U +#endif + bool_t xdr_pmaplist(XDR *xdrs, struct pmaplist **rp) { @@ -53,6 +57,7 @@ xdr_pmaplist(XDR *xdrs, struct pmaplist **rp) bool_t more_elements; int freeing; struct pmaplist *next = NULL; / pacify gcc */ + u_int decoded_nodes = 0; freeing = (xdrs->x_op == XDR_FREE); @@ -67,6 +72,12 @@ xdr_pmaplist(XDR *xdrs, struct pmaplist **rp) if (! more_elements) return (TRUE); + if (xdrs->x_op == XDR_DECODE) { + if (++decoded_nodes > PMAPLIST_DECODE_MAX_NODES) { + return (FALSE); + } + } + if (freeing) next = &((*rp)->pml_next); if (! xdr_reference(xdrs, (caddr_t *)rp, ``` ------ This report was generated using AI technology. Always review AI-generated content prior to use