提交 ba9177c0 编写于 作者: I Ido Schimmel 提交者: Yang Yingliang

bridge: Avoid infinite loop when suppressing NS messages with invalid options

stable inclusion
from linux-4.19.129
commit 1e74500f99567d6532285576925466c368e9665b

--------------------------------

[ Upstream commit 53fc6852 ]

When neighbor suppression is enabled the bridge device might reply to
Neighbor Solicitation (NS) messages on behalf of remote hosts.

In case the NS message includes the "Source link-layer address" option
[1], the bridge device will use the specified address as the link-layer
destination address in its reply.

To avoid an infinite loop, break out of the options parsing loop when
encountering an option with length zero and disregard the NS message.

This is consistent with the IPv6 ndisc code and RFC 4886 which states
that "Nodes MUST silently discard an ND packet that contains an option
with length zero" [2].

[1] https://tools.ietf.org/html/rfc4861#section-4.3
[2] https://tools.ietf.org/html/rfc4861#section-4.6

Fixes: ed842fae ("bridge: suppress nd pkts on BR_NEIGH_SUPPRESS ports")
Signed-off-by: NIdo Schimmel <idosch@mellanox.com>
Reported-by: NAlla Segal <allas@mellanox.com>
Tested-by: NAlla Segal <allas@mellanox.com>
Acked-by: NNikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NLi Aichun <liaichun@huawei.com>
Reviewed-by: Nguodeqing <geffrey.guo@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 3401b861
...@@ -277,6 +277,10 @@ static void br_nd_send(struct net_bridge *br, struct net_bridge_port *p, ...@@ -277,6 +277,10 @@ static void br_nd_send(struct net_bridge *br, struct net_bridge_port *p,
ns_olen = request->len - (skb_network_offset(request) + ns_olen = request->len - (skb_network_offset(request) +
sizeof(struct ipv6hdr)) - sizeof(*ns); sizeof(struct ipv6hdr)) - sizeof(*ns);
for (i = 0; i < ns_olen - 1; i += (ns->opt[i + 1] << 3)) { for (i = 0; i < ns_olen - 1; i += (ns->opt[i + 1] << 3)) {
if (!ns->opt[i + 1]) {
kfree_skb(reply);
return;
}
if (ns->opt[i] == ND_OPT_SOURCE_LL_ADDR) { if (ns->opt[i] == ND_OPT_SOURCE_LL_ADDR) {
daddr = ns->opt + i + sizeof(struct nd_opt_hdr); daddr = ns->opt + i + sizeof(struct nd_opt_hdr);
break; break;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册