dhcp6_parse_ia_options() walks the sub-options encapsulated in a received
IA_NA / IA_TA option and advances its cursor by the sub-option's declared
length alone. A sub-option with a length of zero never advances the
cursor, so the while loop spins forever and the DHCPv6 client hangs. The
advance also omits the sub-option header, so it is short even for
well-formed options.

An attacker on the local link able to answer the client's SOLICIT during
a netboot can send an ADVERTISE whose IA_NA carries a zero-length
encapsulated sub-option and hang the client; the IA_ID it has to match is
observable in the client's SOLICIT.

Advance the cursor by the sub-option header size plus its length so every
iteration makes forward progress and the walk matches the option layout.

Fixes: a0245818f7f8 ("net: dhcp6: Add DHCPv6 (DHCP for IPv6)")
Signed-off-by: Shahriyar Jalayeri <[email protected]>
---
 net/dhcpv6.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/dhcpv6.c b/net/dhcpv6.c
index 640f089a2e1..1e92d744615 100644
--- a/net/dhcpv6.c
+++ b/net/dhcpv6.c
@@ -285,7 +285,8 @@ static void dhcp6_parse_ia_options(struct dhcp6_option_hdr 
*ia_ptr, uchar *ia_op
                        break;
                }
 
-               ia_option_ptr += ntohs(((struct dhcp6_option_hdr 
*)ia_option_ptr)->option_len);
+               ia_option_ptr += sizeof(struct dhcp6_option_hdr) +
+                                ntohs(((struct dhcp6_option_hdr 
*)ia_option_ptr)->option_len);
        }
 }
 

-- 
2.43.0

Reply via email to