On 27 Feb 2026, at 20:01, Mike Pattrick wrote:
> On Thu, Feb 26, 2026 at 5:59 AM Eelco Chaudron via dev < > [email protected]> wrote: > >> Coverity reports a tainted scalar issue (CID 278405) in the >> packet_set_nd() function. The function processes IPv6 Neighbor >> Discovery options from untrusted packet data without properly >> validating the option length field before using it. >> >> The current code: >> while (bytes_remain >= ND_LLA_OPT_LEN && opt->len != 0) { >> ... >> opt += opt->len; >> bytes_remain -= opt->len * ND_LLA_OPT_LEN; >> } >> >> This only checks that at least 8 bytes remain, but doesn't validate >> that the full option (opt->len * ND_LLA_OPT_LEN bytes) fits within >> the remaining buffer. A maliciously crafted packet with an oversized >> opt->len value can cause: >> 1. Pointer advancement beyond packet bounds (opt += opt->len) >> 2. Integer underflow in bytes_remain calculation >> 3. Potential out-of-bounds memory access or infinite loop >> >> Fix this by strengthening the loop condition to validate that the >> full option length fits within bytes_remain before processing it: >> while (opt->len != 0 && bytes_remain >= (opt->len * ND_LLA_OPT_LEN)) >> >> This ensures both the pointer arithmetic and the bytes_remain >> subtraction are always safe. >> >> Fixes: e60e935b1f37 ("Implement set-field for IPv6 ND fields (nd_target, >> nd_sll, and nd_tll).") >> Signed-off-by: Eelco Chaudron <[email protected]> >> --- >> lib/packets.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/lib/packets.c b/lib/packets.c >> index 67e2de4be..654f4ee07 100644 >> --- a/lib/packets.c >> +++ b/lib/packets.c >> @@ -1609,7 +1609,7 @@ packet_set_nd(struct dp_packet *packet, const struct >> in6_addr *target, >> true); >> } >> >> - while (bytes_remain >= ND_LLA_OPT_LEN && opt->len != 0) { >> + while (opt->len != 0 && bytes_remain >= (opt->len * ND_LLA_OPT_LEN)) { >> > > Wouldn't this result in an out of bounds read of opt, which might be beyond > the end of packet? I'd think it should be something like: > > while (bytes_remain > ND_LLA_OPT_LEN && opt->len != 0 && bytes_remain >= > (opt->len * ND_LLA_OPT_LEN)) { Thanks Mike, you are right, I'll fix it in the next revision. _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
