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

Reply via email to