diff options
| author | hannes@stressinduktion.org <hannes@stressinduktion.org> | 2015-04-01 17:07:44 +0200 |
|---|---|---|
| committer | Luis Henriques <luis.henriques@canonical.com> | 2015-04-27 09:48:14 +0100 |
| commit | 426b9be61b3468bd6d2dad275725aebb8aad8f95 (patch) | |
| tree | e6f0bb880287820322ab83e118eb2e45e445d9cd /include/linux | |
| parent | 404b73e72dc127ee8b80a3181ce442997af43f28 (diff) | |
ipv6: protect skb->sk accesses from recursive dereference inside the stack
commit f60e5990d9c1424af9dbca60a23ba2a1c7c1ce90 upstream.
We should not consult skb->sk for output decisions in xmit recursion
levels > 0 in the stack. Otherwise local socket settings could influence
the result of e.g. tunnel encapsulation process.
ipv6 does not conform with this in three places:
1) ip6_fragment: we do consult ipv6_npinfo for frag_size
2) sk_mc_loop in ipv6 uses skb->sk and checks if we should
loop the packet back to the local socket
3) ip6_skb_dst_mtu could query the settings from the user socket and
force a wrong MTU
Furthermore:
In sk_mc_loop we could potentially land in WARN_ON(1) if we use a
PF_PACKET socket ontop of an IPv6-backed vxlan device.
Reuse xmit_recursion as we are currently only interested in protecting
tunnel devices.
Cc: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
[ luis: backported to 3.16: adjusted context ]
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/netdevice.h | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 66f9a04ec270..ab4ce78c5bb8 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1977,6 +1977,12 @@ void netdev_freemem(struct net_device *dev); void synchronize_net(void); int init_dummy_netdev(struct net_device *dev); +DECLARE_PER_CPU(int, xmit_recursion); +static inline int dev_recursion_level(void) +{ + return this_cpu_read(xmit_recursion); +} + struct net_device *dev_get_by_index(struct net *net, int ifindex); struct net_device *__dev_get_by_index(struct net *net, int ifindex); struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex); |
