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)) {
if (opt->type == ND_OPT_SOURCE_LINKADDR && opt->len == 1) {
if (!eth_addr_equals(opt->mac, sll)) {
ovs_be16 *csum = &(ns->icmph.icmp6_cksum);
--
2.52.0
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev