diff options
Diffstat (limited to 'net/core/skbuff.c')
| -rw-r--r-- | net/core/skbuff.c | 16 | 
1 files changed, 11 insertions, 5 deletions
| diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 7e2e502ef519..6faf73d6a0f7 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -820,6 +820,7 @@ void skb_tx_error(struct sk_buff *skb)  }  EXPORT_SYMBOL(skb_tx_error); +#ifdef CONFIG_TRACEPOINTS  /**   *	consume_skb - free an skbuff   *	@skb: buffer to free @@ -837,6 +838,7 @@ void consume_skb(struct sk_buff *skb)  	__kfree_skb(skb);  }  EXPORT_SYMBOL(consume_skb); +#endif  /**   *	consume_stateless_skb - free an skbuff, assuming it is stateless @@ -5418,8 +5420,8 @@ struct sk_buff *skb_vlan_untag(struct sk_buff *skb)  	skb = skb_share_check(skb, GFP_ATOMIC);  	if (unlikely(!skb))  		goto err_free; - -	if (unlikely(!pskb_may_pull(skb, VLAN_HLEN))) +	/* We may access the two bytes after vlan_hdr in vlan_set_encap_proto(). */ +	if (unlikely(!pskb_may_pull(skb, VLAN_HLEN + sizeof(unsigned short))))  		goto err_free;  	vhdr = (struct vlan_hdr *)skb->data; @@ -5987,9 +5989,13 @@ static int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off,  	if (skb_has_frag_list(skb))  		skb_clone_fraglist(skb); -	if (k == 0) { -		/* split line is in frag list */ -		pskb_carve_frag_list(skb, shinfo, off - pos, gfp_mask); +	/* split line is in frag list */ +	if (k == 0 && pskb_carve_frag_list(skb, shinfo, off - pos, gfp_mask)) { +		/* skb_frag_unref() is not needed here as shinfo->nr_frags = 0. */ +		if (skb_has_frag_list(skb)) +			kfree_skb_list(skb_shinfo(skb)->frag_list); +		kfree(data); +		return -ENOMEM;  	}  	skb_release_data(skb); |