History

netfilter: nf_queue: hold bridge skb->dev while queued

br_pass_frame_up() rewrites skb->dev from the ingress port to the bridge master before queueing bridge LOCAL_IN packets. NFQUEUE only holds references on state.in/out and bridge physdevs, so a queued bridge packet can retain a freed bridge master in skb->dev until reinjection. When the verdict is reinjected later, br_netif_receive_skb() re-enters the receive path with skb->dev still pointing at the freed bridge master, triggering a use-after-free. Store skb->dev in the queue entry, hold a reference on it for the queue lifetime, and use the saved device when dropping queued packets during NETDEV_DOWN handling.

Haoze Xie committed 6 months ago

Commit e1961151 parent b2870fc3 files · +6 −1Browse files

Showing the changes to include/net (1 of 3 files). Show all

Unified · Split

include/net/netfilter/nf_queue.h+1−0
@@ -14,6 +14,7 @@ struct nf_queue_entry { · 13 unmodified lines
1414 struct list_head list;
1515 struct rhash_head hash_node;
1616 struct sk_buff *skb;
17+ struct net_device *skb_dev;
1718 unsigned int id;
1819 unsigned int hook_index; /* index in hook_entries->hook[] */
1920 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)