From 75289ca54211481d21b0c915db98dd733b30794f Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Sat, 7 Dec 2024 10:25:44 +0000 Subject: [PATCH] IPv6: Discard NA packets with a zero length option As per RFC 4861 4.6. Fixes #415. --- src/ipv6nd.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/ipv6nd.c b/src/ipv6nd.c index cc42c569..bfaf9274 100644 --- a/src/ipv6nd.c +++ b/src/ipv6nd.c @@ -974,6 +974,12 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, bool new_ia; #endif +#define FREE_RAP(rap) \ + if (new_rap) \ + ipv6nd_removefreedrop_ra(rap, 0, 0); \ + else \ + ipv6nd_free_ra(rap); \ + if (ifp == NULL || RS_STATE(ifp) == NULL) { #ifdef DEBUG_RS logdebugx("RA for unexpected interface from %s", sfrom); @@ -1130,8 +1136,10 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, memcpy(&ndo, p, sizeof(ndo)); olen = (size_t)ndo.nd_opt_len * 8; if (olen == 0) { + /* RFC4681 4.6 says we MUST discard this ND packet. */ logerrx("%s: zero length option", ifp->name); - break; + FREE_RAP(rap); + return; } if (olen > len) { logerrx("%s: option length exceeds message", @@ -1155,10 +1163,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, else logwarnx("%s: reject RA (option %d) from %s", ifp->name, ndo.nd_opt_type, rap->sfrom); - if (new_rap) - ipv6nd_removefreedrop_ra(rap, 0, 0); - else - ipv6nd_free_ra(rap); + FREE_RAP(rap); return; } @@ -1409,10 +1414,7 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, { logwarnx("%s: reject RA (no option %s) from %s", ifp->name, dho->var, rap->sfrom); - if (new_rap) - ipv6nd_removefreedrop_ra(rap, 0, 0); - else - ipv6nd_free_ra(rap); + FREE_RAP(rap); return; } } @@ -1494,6 +1496,7 @@ nodhcp6: /* Expire should be called last as the rap object could be destroyed */ ipv6nd_expirera(ifp); +#undef FREE_RAP } bool -- 2.47.2