Commit e150d409 ("packets: Validate ND option length in
packet_set_nd().", Coverity CID 278405) added a bounds check to the
Neighbor Discovery option walk in packet_set_nd(), but the
structurally identical option walk in odp_set_nd() was left unguarded.
odp_set_nd() walks the ND link-layer-address options to locate the SLL
or TLL option before delegating the actual packet edit to
packet_set_nd(). Its loop only checks that ND_LLA_OPT_LEN bytes remain
and that lla_opt->len is non-zero; it does not verify that the full
option (lla_opt->len * ND_LLA_OPT_LEN bytes) fits within bytes_remain
before advancing past it. A crafted ND packet carrying an oversized
option length therefore advances lla_opt beyond the L4 payload and
underflows bytes_remain, and the next iteration reads lla_opt->type /
lla_opt->len out of bounds. This is the same defect, in the same
option-walk pattern, that CID 278405 reported for packet_set_nd().
Apply the same loop condition used by the parent fix so an option is
only processed when it fully fits within the remaining bytes.
Fixes: e60e935b1f37 ("Implement set-field for IPv6 ND fields (nd_target,
nd_sll, and nd_tll).")
Signed-off-by: Yuliang Xiao <[email protected]>
---
lib/odp-execute.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/odp-execute.c b/lib/odp-execute.c
index 4642f3375..e3e56e2dd 100644
--- a/lib/odp-execute.c
+++ b/lib/odp-execute.c
@@ -356,7 +356,8 @@ odp_set_nd(struct dp_packet *packet, const struct
ovs_key_nd *key,
struct eth_addr sll_buf = eth_addr_zero;
struct eth_addr tll_buf = eth_addr_zero;
- while (bytes_remain >= ND_LLA_OPT_LEN && lla_opt->len != 0) {
+ while (bytes_remain >= ND_LLA_OPT_LEN && lla_opt->len != 0
+ && bytes_remain >= (lla_opt->len * ND_LLA_OPT_LEN)) {
if (lla_opt->type == ND_OPT_SOURCE_LINKADDR
&& lla_opt->len == 1) {
sll_buf = lla_opt->mac;
--
2.27.0
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev