diff options
Diffstat (limited to 'net/ipv4/esp4.c')
| -rw-r--r-- | net/ipv4/esp4.c | 20 | 
1 files changed, 15 insertions, 5 deletions
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 10e809b296ec..fb065a8937ea 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -226,7 +226,7 @@ static void esp_output_fill_trailer(u8 *tail, int tfclen, int plen, __u8 proto)  	tail[plen - 1] = proto;  } -static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp) +static int esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp)  {  	int encap_type;  	struct udphdr *uh; @@ -234,6 +234,7 @@ static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, stru  	__be16 sport, dport;  	struct xfrm_encap_tmpl *encap = x->encap;  	struct ip_esp_hdr *esph = esp->esph; +	unsigned int len;  	spin_lock_bh(&x->lock);  	sport = encap->encap_sport; @@ -241,11 +242,14 @@ static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, stru  	encap_type = encap->encap_type;  	spin_unlock_bh(&x->lock); +	len = skb->len + esp->tailen - skb_transport_offset(skb); +	if (len + sizeof(struct iphdr) >= IP_MAX_MTU) +		return -EMSGSIZE; +  	uh = (struct udphdr *)esph;  	uh->source = sport;  	uh->dest = dport; -	uh->len = htons(skb->len + esp->tailen -		  - skb_transport_offset(skb)); +	uh->len = htons(len);  	uh->check = 0;  	switch (encap_type) { @@ -262,6 +266,8 @@ static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, stru  	*skb_mac_header(skb) = IPPROTO_UDP;  	esp->esph = esph; + +	return 0;  }  int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp) @@ -275,8 +281,12 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *  	int tailen = esp->tailen;  	/* this is non-NULL only with UDP Encapsulation */ -	if (x->encap) -		esp_output_udp_encap(x, skb, esp); +	if (x->encap) { +		int err = esp_output_udp_encap(x, skb, esp); + +		if (err < 0) +			return err; +	}  	if (!skb_cloned(skb)) {  		if (tailen <= skb_tailroom(skb)) {  | 
