bridge: Fix crash with vlan filtering and tcpdump

When the vlan filtering is enabled on the bridge, but
the filter is not configured on the bridge device itself,
running tcpdump on the bridge device will result in a
an Oops with NULL pointer dereference. The reason
is that br_pass_frame_up() will bypass the vlan
check because promisc flag is set. It will then try
to get the table pointer and process the packet based
on the table. Since the table pointer is NULL, we oops.
Catch this special condition in br_handle_vlan().

Reported-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
CC: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
Acked-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Vlad Yasevich and committed by David S. Miller fc92f745 53d6471c

Changed files
+20 -5
net
+6 -5
net/bridge/br_input.c
··· 29 29 struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev; 30 30 struct net_bridge *br = netdev_priv(brdev); 31 31 struct pcpu_sw_netstats *brstats = this_cpu_ptr(br->stats); 32 + struct net_port_vlans *pv; 32 33 33 34 u64_stats_update_begin(&brstats->syncp); 34 35 brstats->rx_packets++; ··· 40 39 * packet is allowed except in promisc modue when someone 41 40 * may be running packet capture. 42 41 */ 42 + pv = br_get_vlan_info(br); 43 43 if (!(brdev->flags & IFF_PROMISC) && 44 - !br_allowed_egress(br, br_get_vlan_info(br), skb)) { 44 + !br_allowed_egress(br, pv, skb)) { 45 45 kfree_skb(skb); 46 46 return NET_RX_DROP; 47 47 } 48 48 49 - skb = br_handle_vlan(br, br_get_vlan_info(br), skb); 50 - if (!skb) 51 - return NET_RX_DROP; 52 - 53 49 indev = skb->dev; 54 50 skb->dev = brdev; 51 + skb = br_handle_vlan(br, pv, skb); 52 + if (!skb) 53 + return NET_RX_DROP; 55 54 56 55 return NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, 57 56 netif_receive_skb);
+14
net/bridge/br_vlan.c
··· 128 128 if (!br->vlan_enabled) 129 129 goto out; 130 130 131 + /* Vlan filter table must be configured at this point. The 132 + * only exception is the bridge is set in promisc mode and the 133 + * packet is destined for the bridge device. In this case 134 + * pass the packet as is. 135 + */ 136 + if (!pv) { 137 + if ((br->dev->flags & IFF_PROMISC) && skb->dev == br->dev) { 138 + goto out; 139 + } else { 140 + kfree_skb(skb); 141 + return NULL; 142 + } 143 + } 144 + 131 145 /* At this point, we know that the frame was filtered and contains 132 146 * a valid vlan id. If the vlan id is set in the untagged bitmap, 133 147 * send untagged; otherwise, send tagged.