Fedora Account System
Red Hat Associate
Red Hat Customer
AI_ONLY_REPORT package: iscsi-initiator-utils-6.2.1.11-0.git4b3e853.el10 ------ Summary: Infinite Loop in ICMPv6 Router Advertisement Parsing: a crafted on-link ICMPv6 Router Advertisement with a zero-length option can hang `iscsiuio` in a non-terminating parse loop, and a short IPv6 payload can also underflow the option length and drive out-of-bounds reads. Requirements to exploit: An attacker must be able to send ICMPv6 Router Advertisements from the same L2 segment to an IPv6-enabled interface handled by `iscsiuio`. In the observed code, repeated exploitation may depend on the current IPv6 context because the handler returns early once `IPV6_FLAGS_ROUTER_ADV_RECEIVED` is set. Component affected: `iscsi-initiator-utils-6.2.1.11-0.git4b3e853.el10`, `iscsiuio/src/uip/ipv6.c`, `ipv6_icmp_handle_router_adv()` Version affected: `iscsi-initiator-utils-6.2.1.11-0.git4b3e853.el10` where `iscsiuio` processes ICMPv6 Router Advertisements on an IPv6-enabled interface Patch available: no released package fix established; proposed patch included below Version fixed: unknown Upstream coordination: Not notified. CVSS: CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - 6.5 (MEDIUM) AV:A - The attack requires delivery of a crafted Router Advertisement from the same L2 or adjacent network. AC:L - A malformed RA with a zero-length option or a short payload is sufficient; no race or special timing was established. PR:N - No authentication or prior access to the target host is required. UI:N - No user interaction is needed once the packet reaches the daemon. S:U - The impact is limited to the `iscsiuio` process handling the packet. C:N - The available evidence does not establish unauthorized disclosure of protected data. I:N - The available evidence does not establish data modification or code execution. A:H - The parser can enter a non-terminating loop and render the daemon unresponsive with sustained CPU use. Impact: Moderate. The confirmed outcome is denial of service against `iscsiuio`, not system compromise or arbitrary code execution. While the attack is straightforward once reachable, reachability is constrained by adjacent-network access and an IPv6-enabled deployment that processes Router Advertisements, so Red Hat's Moderate classification is a better fit than Important for the evidence currently available. Embargo: no Reason: This is a configuration-dependent adjacent-network denial of service with practical operational mitigations, and the available evidence does not support code execution, privilege escalation, or data exposure. Acknowledgement: Aisle Research Vulnerability Details: `ipv6_icmp_handle_router_adv()` derives the Router Advertisement option area length from the IPv6 payload length and then advances through options by adding `icmp_opt->len * 8` to the current offset. The parser does not reject a zero-length option and does not verify that the payload length is at least the size of `struct icmpv6_router_advert` before subtracting it. ```c opt_len = HOST_TO_NET16(ipv6->ipv6_plen) - sizeof(struct icmpv6_router_advert); len = 0; while (len < opt_len) { icmp_opt = (struct icmpv6_opt_hdr *)((u8_t *)icmp + sizeof(struct icmpv6_router_advert) + len); ... len += icmp_opt->len * 8; } ``` If `icmp_opt->len` is `0`, `len` never increases and the loop does not terminate, causing a sustained CPU-consuming hang in `iscsiuio`. Separately, if `ipv6->ipv6_plen` is smaller than `sizeof(struct icmpv6_router_advert)` (`16`), the unsigned subtraction underflows and produces an oversized `opt_len`, which can drive reads past the valid option data. This corresponds to a non-progress loop (CWE-835) and an unsigned length underflow with out-of-bounds read risk (CWE-191 / CWE-125). The available material supports the read overrun as a secondary risk, but does not establish memory corruption or confidentiality/integrity impact. The parser is reached through `uip.c -> UIP_NDP_CALL -> ipv6_rx_packet() -> ipv6_icmp_rx() -> ipv6_icmp_handle_router_adv()`. No RA-specific minimum-length, zero-length-option, or per-option bounds checks were identified before this loop. Steps to reproduce: 1. Run `iscsiuio` on an IPv6-enabled interface where it processes ICMPv6 Router Advertisements. 2. From an adjacent host on the same L2 segment, send an ICMPv6 Router Advertisement with `type=134` and an option header whose `len` field is `0`. 3. Observe that the parser does not return, CPU utilization stays elevated, and IPv6/NDP progress through `iscsiuio` stalls. 4. Optional variant: send an RA with `ipv6_plen < 16` to underflow `opt_len` and drive invalid option walking before the hang or fault behavior. 5. Confirm loss of forward progress via process behavior, logs, or lack of further protocol activity. Mitigation: Until a fix is available, limit or filter ICMPv6 Router Advertisements from untrusted hosts on any L2 segment that reaches interfaces handled by `iscsiuio`. Where operationally acceptable, avoid exposing affected `iscsiuio` interfaces to untrusted adjacent IPv6 traffic or disable RA-driven IPv6 configuration on those interfaces. Proposed Fix: Add explicit minimum-length, zero-length-option, and per-option bounds checks before advancing through the Router Advertisement option list. ```diff diff --git a/iscsiuio/src/uip/ipv6.c b/iscsiuio/src/uip/ipv6.c @@ -850,6 +850,7 @@ static void ipv6_icmp_handle_router_adv(struct ipv6_context *context) struct icmpv6_router_advert *icmp = (struct icmpv6_router_advert *)((u8_t *)ipv6 + sizeof(struct ipv6_hdr)); struct icmpv6_opt_hdr *icmp_opt; + u16_t payload_len; u16_t opt_len; u16_t len; char addr_str[INET6_ADDRSTRLEN]; @@ -857,8 +858,13 @@ static void ipv6_icmp_handle_router_adv(struct ipv6_context *context) if (context->flags & IPV6_FLAGS_ROUTER_ADV_RECEIVED) return; opt_len = HOST_TO_NET16(ipv6>ipv6_plen) - - sizeof(struct icmpv6_router_advert); + payload_len = HOST_TO_NET16(ipv6->ipv6_plen); + if (payload_len < sizeof(struct icmpv6_router_advert)) + return; + + opt_len = payload_len - sizeof(struct icmpv6_router_advert); icmp_opt = (struct icmpv6_opt_hdr *)((u8_t *)icmp + sizeof(struct icmpv6_router_advert)); len = 0; - while (len < opt_len) { + while (len + sizeof(struct icmpv6_opt_hdr) <= opt_len) { + u16_t step; icmp_opt = (struct icmpv6_opt_hdr *)((u8_t *)icmp + sizeof(struct icmpv6_router_advert) + len); + if (icmp_opt->len == 0) + break; + step = (u16_t)icmp_opt->len * 8; + if (len + step > opt_len) + break; @@ -879,7 +885,7 @@ static void ipv6_icmp_handle_router_adv(struct ipv6_context *context) break; } len += icmp_opt>len * 8; + len += step; } ``` ------ This report was generated using AI technology. Always review AI-generated content prior to use