summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2020-06-01 11:08:41 -0700
committerDavid S. Miller <davem@davemloft.net>2020-06-01 11:08:41 -0700
commitd36ceaef8fc2e4ede43de425a7f503013b500e7f (patch)
tree271f479c669e2291e74a6e548f68fbff86052d84
parentdafe2078a75af1abe4780313ef8dd8491ba8598f (diff)
parent8066e6b449e050675df48e7c4b16c29f00507ff0 (diff)
Merge branch 'Fix-infinite-loop-in-bridge-and-vxlan-modules'
Ido Schimmel says: ==================== Fix infinite loop in bridge and vxlan modules When suppressing invalid IPv6 Neighbour Solicitation messages, it is possible for the bridge and vxlan modules to get stuck in an infinite loop. See the individual changelogs for detailed explanation of the problem and solution. The bug was originally reported against the bridge module, but after auditing the code base I found that the buggy code was copied from the vxlan module. This patch set fixes both modules. Could not find more instances of the problem. Please consider both patches for stable releases. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/vxlan.c4
-rw-r--r--net/bridge/br_arp_nd_proxy.c4
2 files changed, 8 insertions, 0 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 39bc10a7fd2e..d5906b41cdae 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -2092,6 +2092,10 @@ static struct sk_buff *vxlan_na_create(struct sk_buff *request,
ns_olen = request->len - skb_network_offset(request) -
sizeof(struct ipv6hdr) - sizeof(*ns);
for (i = 0; i < ns_olen-1; i += (ns->opt[i+1]<<3)) {
+ if (!ns->opt[i + 1]) {
+ kfree_skb(reply);
+ return NULL;
+ }
if (ns->opt[i] == ND_OPT_SOURCE_LL_ADDR) {
daddr = ns->opt + i + sizeof(struct nd_opt_hdr);
break;
diff --git a/net/bridge/br_arp_nd_proxy.c b/net/bridge/br_arp_nd_proxy.c
index 37908561a64b..b18cdf03edb3 100644
--- a/net/bridge/br_arp_nd_proxy.c
+++ b/net/bridge/br_arp_nd_proxy.c
@@ -276,6 +276,10 @@ static void br_nd_send(struct net_bridge *br, struct net_bridge_port *p,
ns_olen = request->len - (skb_network_offset(request) +
sizeof(struct ipv6hdr)) - sizeof(*ns);
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) {
daddr = ns->opt + i + sizeof(struct nd_opt_hdr);
break;