Fedora Account System
Red Hat Associate
Red Hat Customer
AI_ONLY_REPORT package: iscsi-initiator-utils-6.2.1.11-0.git4b3e853.el10 ------ Summary: Integer Underflow and Out-of-Bounds Read in DHCPv6 Packet Parsing: crafted DHCPv6 Advertise traffic with a short UDP length can underflow the DHCPv6 payload length, drive option parsing past packet bounds, and likely cause a denial of service in the `iscsiuio` DHCPv6 client path. Requirements to exploit: The attacker needs adjacent network access on the same L2 segment as a system running `iscsiuio` with DHCPv6 enabled, plus the ability to send forged IPv6 UDP traffic from source port `547` to destination port `546` while the client is in an active DHCPv6 exchange. A matching transaction ID is also required; the reviewed material indicates this can be obtained by sniffing a Solicit or by brute-forcing the 16-bit value checked by the implementation. Component affected: `iscsi-initiator-utils` (`iscsiuio` DHCPv6 receive path), specifically `iscsiuio/src/uip/ipv6.c` in `ipv6_udp_rx()` and `iscsiuio/src/apps/dhcpc/dhcpv6.c` in `ipv6_udp_handle_dhcp()` / `dhcpv6_handle_advertise()`. Version affected: `iscsi-initiator-utils-6.2.1.11-0.git4b3e853.el10` when DHCPv6 handling in `iscsiuio` is enabled and reachable. 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 attacker must be on an adjacent network segment able to inject DHCPv6 traffic to the victim. AC:L - Packet construction is straightforward once the DHCPv6 transaction value is known or guessed, and no special conditions beyond an active DHCPv6 exchange are established. PR:N - No authentication or existing privileges are required. UI:N - No user interaction is needed. S:U - The impact is confined to the vulnerable `iscsiuio` component and does not cross a security boundary. C:N - The available evidence shows out-of-bounds reads, but does not establish a confidentiality disclosure. I:N - The available evidence does not show data modification or code execution. A:H - The likely outcome is process crash or comparable service disruption in the DHCPv6 path. Impact: Moderate. The currently supported impact is an adjacent-network denial of service in the DHCPv6 receive path. Although the attacker is unauthenticated, exploitability is narrower than a typical remote DoS because DHCPv6 must be enabled, the client must be in the relevant exchange state, and the packet must satisfy the transaction check. The available evidence does not establish confidentiality, integrity, or full system compromise, so Moderate better fits Red Hat's severity guidance than Important. Embargo: no Reason: The supported impact is a constrained adjacent-network availability issue with practical mitigations, not an easily exploitable remote compromise or wormable condition. Acknowledgement: Aisle Research Vulnerability Details: The DHCPv6 receive path dispatches packets to the DHCPv6 parser based on UDP ports without first rejecting undersized or inconsistent UDP length values. It then derives `dhcpv6_len` using unsigned arithmetic and uses the result as the bound for DHCPv6 Advertise option parsing: ```c if ((udp->src_port == HOST_TO_NET16(DHCPV6_SERVER_PORT)) && (udp->dest_port == HOST_TO_NET16(DHCPV6_CLIENT_PORT))) { ... ipv6_udp_handle_dhcp(dhcpv6c); } ... dhcpv6_len = NET_TO_HOST16(context->udp->length) - sizeof(struct udp_hdr); ... while (i < (dhcpv6_len - sizeof(union dhcpv6_hdr))) { ... } ``` If `udp->length` is smaller than `sizeof(struct udp_hdr)` (`8`), the subtraction underflows in `u16_t` and produces a large wrapped value. The Advertise parser then uses that wrapped value as the loop bound while walking DHCPv6 options, leading to reads beyond the actual packet data. The available report also indicates that no earlier receive-path check enforces UDP length consistency before `ipv6_udp_handle_dhcp()` is reached. Based on the available evidence, the practical consequence is likely process crash or similar denial of service; the current record does not establish arbitrary code execution or a proven confidentiality impact. Steps to reproduce: 1. Configure a target with IPv6 DHCP mode enabled (`IPV6_CONFIG_DHCP`) on a shared L2 segment. 2. Wait until the client is in the DHCPv6 solicit phase (`DHCPV6_STATE_SOLICIT_SENT`). 3. Capture one outbound DHCPv6 Solicit to obtain the current transaction ID, or brute-force the 16-bit value checked by the implementation. 4. Send a forged IPv6 UDP packet to the victim with source port `547`, destination port `546`, DHCPv6 message type `ADVERTISE`, a matching transaction ID, and a UDP header `length` smaller than `8` such as `4`. 5. Observe out-of-bounds reads during the Advertise option parsing loop; based on the available evidence this is plausibly crash-inducing and can produce a denial of service. Mitigation: If DHCPv6 is not required, disable DHCPv6 handling in `iscsiuio`. Where DHCPv6 is required, restrict exposure to trusted adjacent networks and prevent forged DHCPv6 server traffic from reaching clients on shared L2 segments until a fixed package is available. Proposed Fix: Reject DHCPv6 packets whose IPv6 and UDP length fields are too short or inconsistent before dispatching them to the DHCPv6 parser, and refuse to subtract the UDP header size unless the UDP length is large enough to contain it. ```diff diff --git a/iscsiuio/src/uip/ipv6.c b/iscsiuio/src/uip/ipv6.c @@ -1220,6 +1220,8 @@ static void ipv6_udp_rx(struct ipv6_context *context) struct udp_hdr *udp = (struct udp_hdr *)((u8_t *)ipv6 + sizeof(struct ipv6_hdr)); struct dhcpv6_context *dhcpv6c; + u16_t ipv6_plen = NET_TO_HOST16(ipv6->ipv6_plen); + u16_t udp_len = NET_TO_HOST16(udp->length); @@ -1230,6 +1232,14 @@ static void ipv6_udp_rx(struct ipv6_context *context) if (!(context->flags & IPV6_FLAGS_DISABLE_DHCPV6)) { if ((udp->src_port == HOST_TO_NET16(DHCPV6_SERVER_PORT)) && (udp->dest_port == HOST_TO_NET16(DHCPV6_CLIENT_PORT))) { + /* Require minimal UDP + DHCPv6 fixed header and consistency */ + if (ipv6_plen < sizeof(struct udp_hdr) + sizeof(union dhcpv6_hdr)) + return; + if (udp_len < sizeof(struct udp_hdr) + sizeof(union dhcpv6_hdr)) + return; + if (udp_len > ipv6_plen) + return; + dhcpv6c = context->dhcpv6_context; dhcpv6c->eth = eth; dhcpv6c->ipv6 = ipv6; diff --git a/iscsiuio/src/apps/dhcpc/dhcpv6.c b/iscsiuio/src/apps/dhcpc/dhcpv6.c @@ -258,6 +258,7 @@ void ipv6_udp_handle_dhcp(struct dhcpv6_context *context) union dhcpv6_hdr *dhcpv6; u16_t dhcpv6_len; + u16_t udp_len = NET_TO_HOST16(context->udp->length); if (context->dhcpv6_done == TRUE) return; @@ -273,8 +274,12 @@ void ipv6_udp_handle_dhcp(struct dhcpv6_context *context) return; } - dhcpv6_len = NET_TO_HOST16(context>udp->length) - sizeof(struct udp_hdr); + if (udp_len < sizeof(struct udp_hdr)) + return; + dhcpv6_len = udp_len - sizeof(struct udp_hdr); + + if (dhcpv6_len < sizeof(union dhcpv6_hdr)) + return; ``` ------ This report was generated using AI technology. Always review AI-generated content prior to use