From: Felix Fietkau Date: Tue, 31 May 2022 12:01:21 +0000 (+0200) Subject: kernel: fix crashes in bridge offload code X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=38a5b593ef9e94deedefb627f1952b3bb881df56;p=openwrt%2Fstaging%2Fstintel.git kernel: fix crashes in bridge offload code - fix an issues when accessing the port pointer of an expired/invalid fdb entry Signed-off-by: Felix Fietkau --- diff --git a/target/linux/generic/hack-5.10/600-bridge_offload.patch b/target/linux/generic/hack-5.10/600-bridge_offload.patch index 586353816c..7e1b852bf3 100644 --- a/target/linux/generic/hack-5.10/600-bridge_offload.patch +++ b/target/linux/generic/hack-5.10/600-bridge_offload.patch @@ -434,13 +434,13 @@ + vg = nbp_vlan_group_rcu(inp); + vlan = cb->input_vlan_present ? cb->input_vlan_tag : br_get_pvid(vg); + fdb_in = br_fdb_find_rcu(p->br, eth_hdr(skb)->h_source, vlan); -+ if (!fdb_in) ++ if (!fdb_in || !fdb_in->dst) + goto out; + + vg = nbp_vlan_group_rcu(p); + vlan = skb_vlan_tag_present(skb) ? skb_vlan_tag_get_id(skb) : br_get_pvid(vg); + fdb_out = br_fdb_find_rcu(p->br, eth_hdr(skb)->h_dest, vlan); -+ if (!fdb_out) ++ if (!fdb_out || !fdb_out->dst) + goto out; + + br_offload_prepare_key(p, &key, skb); @@ -450,7 +450,7 @@ +#endif + + flow = kmem_cache_alloc(offload_cache, GFP_ATOMIC); -+ flow->port = fdb_in->dst; ++ flow->port = inp; + memcpy(&flow->key, &key, sizeof(key)); + +#ifdef CONFIG_BRIDGE_VLAN_FILTERING @@ -465,7 +465,7 @@ + spin_lock_bh(&offload_lock); + if (!o->enabled || + atomic_read(&p->offload.rht.nelems) >= p->br->offload_cache_size || -+ rhashtable_insert_fast(&flow->port->offload.rht, &flow->node, flow_params)) { ++ rhashtable_insert_fast(&inp->offload.rht, &flow->node, flow_params)) { + kmem_cache_free(offload_cache, flow); + goto out_unlock; + } @@ -511,8 +511,8 @@ +#ifdef CONFIG_BRIDGE_VLAN_FILTERING + cb->input_vlan_present = key.vlan_present != 0; + cb->input_vlan_tag = key.vlan_tag; -+ cb->input_ifindex = p->dev->ifindex; +#endif ++ cb->input_ifindex = p->dev->ifindex; + goto out; + } + diff --git a/target/linux/generic/hack-5.15/600-bridge_offload.patch b/target/linux/generic/hack-5.15/600-bridge_offload.patch index c7942a0aef..b396d748b6 100644 --- a/target/linux/generic/hack-5.15/600-bridge_offload.patch +++ b/target/linux/generic/hack-5.15/600-bridge_offload.patch @@ -434,13 +434,13 @@ + vg = nbp_vlan_group_rcu(inp); + vlan = cb->input_vlan_present ? cb->input_vlan_tag : br_get_pvid(vg); + fdb_in = br_fdb_find_rcu(p->br, eth_hdr(skb)->h_source, vlan); -+ if (!fdb_in) ++ if (!fdb_in || !fdb_in->dst) + goto out; + + vg = nbp_vlan_group_rcu(p); + vlan = skb_vlan_tag_present(skb) ? skb_vlan_tag_get_id(skb) : br_get_pvid(vg); + fdb_out = br_fdb_find_rcu(p->br, eth_hdr(skb)->h_dest, vlan); -+ if (!fdb_out) ++ if (!fdb_out || !fdb_out->dst) + goto out; + + br_offload_prepare_key(p, &key, skb); @@ -450,7 +450,7 @@ +#endif + + flow = kmem_cache_alloc(offload_cache, GFP_ATOMIC); -+ flow->port = fdb_in->dst; ++ flow->port = inp; + memcpy(&flow->key, &key, sizeof(key)); + +#ifdef CONFIG_BRIDGE_VLAN_FILTERING @@ -465,7 +465,7 @@ + spin_lock_bh(&offload_lock); + if (!o->enabled || + atomic_read(&p->offload.rht.nelems) >= p->br->offload_cache_size || -+ rhashtable_insert_fast(&flow->port->offload.rht, &flow->node, flow_params)) { ++ rhashtable_insert_fast(&inp->offload.rht, &flow->node, flow_params)) { + kmem_cache_free(offload_cache, flow); + goto out_unlock; + } @@ -511,8 +511,8 @@ +#ifdef CONFIG_BRIDGE_VLAN_FILTERING + cb->input_vlan_present = key.vlan_present != 0; + cb->input_vlan_tag = key.vlan_tag; -+ cb->input_ifindex = p->dev->ifindex; +#endif ++ cb->input_ifindex = p->dev->ifindex; + goto out; + } +