forked from mirrors/linux
		
	net: core: fix use-after-free in __netif_receive_skb_list_core
__netif_receive_skb_core can free the skb, so we have to use the dequeue-
 enqueue model when calling it from __netif_receive_skb_list_core.
Fixes: 88eb1944e1 ("net: core: propagate SKB lists through packet_type lookup")
Signed-off-by: Edward Cree <ecree@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
			
			
This commit is contained in:
		
							parent
							
								
									9f17dbf04d
								
							
						
					
					
						commit
						9af86f9338
					
				
					 1 changed files with 7 additions and 2 deletions
				
			
		|  | @ -4830,23 +4830,28 @@ static void __netif_receive_skb_list_core(struct list_head *head, bool pfmemallo | ||||||
| 	struct list_head sublist; | 	struct list_head sublist; | ||||||
| 	struct sk_buff *skb, *next; | 	struct sk_buff *skb, *next; | ||||||
| 
 | 
 | ||||||
|  | 	INIT_LIST_HEAD(&sublist); | ||||||
| 	list_for_each_entry_safe(skb, next, head, list) { | 	list_for_each_entry_safe(skb, next, head, list) { | ||||||
| 		struct net_device *orig_dev = skb->dev; | 		struct net_device *orig_dev = skb->dev; | ||||||
| 		struct packet_type *pt_prev = NULL; | 		struct packet_type *pt_prev = NULL; | ||||||
| 
 | 
 | ||||||
|  | 		list_del(&skb->list); | ||||||
| 		__netif_receive_skb_core(skb, pfmemalloc, &pt_prev); | 		__netif_receive_skb_core(skb, pfmemalloc, &pt_prev); | ||||||
|  | 		if (!pt_prev) | ||||||
|  | 			continue; | ||||||
| 		if (pt_curr != pt_prev || od_curr != orig_dev) { | 		if (pt_curr != pt_prev || od_curr != orig_dev) { | ||||||
| 			/* dispatch old sublist */ | 			/* dispatch old sublist */ | ||||||
| 			list_cut_before(&sublist, head, &skb->list); |  | ||||||
| 			__netif_receive_skb_list_ptype(&sublist, pt_curr, od_curr); | 			__netif_receive_skb_list_ptype(&sublist, pt_curr, od_curr); | ||||||
| 			/* start new sublist */ | 			/* start new sublist */ | ||||||
|  | 			INIT_LIST_HEAD(&sublist); | ||||||
| 			pt_curr = pt_prev; | 			pt_curr = pt_prev; | ||||||
| 			od_curr = orig_dev; | 			od_curr = orig_dev; | ||||||
| 		} | 		} | ||||||
|  | 		list_add_tail(&skb->list, &sublist); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* dispatch final sublist */ | 	/* dispatch final sublist */ | ||||||
| 	__netif_receive_skb_list_ptype(head, pt_curr, od_curr); | 	__netif_receive_skb_list_ptype(&sublist, pt_curr, od_curr); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int __netif_receive_skb(struct sk_buff *skb) | static int __netif_receive_skb(struct sk_buff *skb) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Edward Cree
						Edward Cree