Commit d36ceaef authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents dafe2078 8066e6b4
...@@ -2092,6 +2092,10 @@ static struct sk_buff *vxlan_na_create(struct sk_buff *request, ...@@ -2092,6 +2092,10 @@ static struct sk_buff *vxlan_na_create(struct sk_buff *request,
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 NULL;
}
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;
......
...@@ -276,6 +276,10 @@ static void br_nd_send(struct net_bridge *br, struct net_bridge_port *p, ...@@ -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) + 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%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment