diff options
author | David S. Miller <davem@davemloft.net> | 2019-07-02 11:53:03 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-07-02 11:53:03 -0700 |
commit | f2f1717592d4790790bdcc73dbbe4958d2d33198 (patch) | |
tree | 0907ef038036f75e1914101b73be9891a42ac7d4 /net/bridge/br_input.c | |
parent | r8152: fix the setting of detecting the linking change for runtime suspend (diff) | |
parent | net: bridge: stp: don't cache eth dest pointer before skb pull (diff) | |
download | linux-dev-f2f1717592d4790790bdcc73dbbe4958d2d33198.tar.xz linux-dev-f2f1717592d4790790bdcc73dbbe4958d2d33198.zip |
Merge branch 'bridge-stale-ptrs'
Nikolay Aleksandrov says:
====================
net: bridge: fix possible stale skb pointers
In the bridge driver we have a couple of places which call pskb_may_pull
but we've cached skb pointers before that and use them after which can
lead to out-of-bounds/stale pointer use. I've had these in my "to fix"
list for some time and now we got a report (patch 01) so here they are.
Patches 02-04 are fixes based on code inspection. Also patch 01 was
tested by Martin Weinelt, Martin if you don't mind please add your
tested-by tag to it by replying with Tested-by: name <email>.
I've also briefly tested the set by trying to exercise those code paths.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to '')
-rw-r--r-- | net/bridge/br_input.c | 8 |
1 files changed, 3 insertions, 5 deletions
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 21b74e7a7b2f..52c712984cc7 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -74,7 +74,6 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb struct net_bridge_fdb_entry *dst = NULL; struct net_bridge_mdb_entry *mdst; bool local_rcv, mcast_hit = false; - const unsigned char *dest; struct net_bridge *br; u16 vid = 0; @@ -92,10 +91,9 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb br_fdb_update(br, p, eth_hdr(skb)->h_source, vid, false); local_rcv = !!(br->dev->flags & IFF_PROMISC); - dest = eth_hdr(skb)->h_dest; - if (is_multicast_ether_addr(dest)) { + if (is_multicast_ether_addr(eth_hdr(skb)->h_dest)) { /* by definition the broadcast is also a multicast address */ - if (is_broadcast_ether_addr(dest)) { + if (is_broadcast_ether_addr(eth_hdr(skb)->h_dest)) { pkt_type = BR_PKT_BROADCAST; local_rcv = true; } else { @@ -145,7 +143,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb } break; case BR_PKT_UNICAST: - dst = br_fdb_find_rcu(br, dest, vid); + dst = br_fdb_find_rcu(br, eth_hdr(skb)->h_dest, vid); default: break; } |