summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKazunori Miyazawa <kazunori@miyazawa.org>2003-08-07 07:49:41 -0700
committerStephen Hemminger <shemminger@osdl.org>2003-08-07 07:49:41 -0700
commit99c2a90294b7734b80de6f1650356df3f5879462 (patch)
tree85b525f316fa3e87528165b7d33cb752ff2823a8
parente8830aa5f1f50656ff7614ae3b21e40805795786 (diff)
[IPV6]: Fix clearing in ah6 input.
This patch fixes zero-clear in ah6_input. If calling pskb_expand_head, the kernel clears wrong memory.
-rw-r--r--net/ipv6/ah6.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 07d92a2e48a3..c13efb13eaf9 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -265,13 +265,12 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu
* There is offset of AH before IPv6 header after the process.
*/
- struct ipv6hdr *iph = skb->nh.ipv6h;
struct ipv6_auth_hdr *ah;
struct ah_data *ahp;
unsigned char *tmp_hdr = NULL;
- u16 hdr_len = skb->data - skb->nh.raw;
+ u16 hdr_len;
u16 ah_hlen;
- u16 cleared_hlen = hdr_len;
+ u16 cleared_hlen;
u16 nh_offset = 0;
u8 nexthdr = 0;
u8 *prevhdr;
@@ -279,6 +278,14 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu
if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr)))
goto out;
+ /* We are going to _remove_ AH header to keep sockets happy,
+ * so... Later this can change. */
+ if (skb_cloned(skb) &&
+ pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+ goto out;
+
+ hdr_len = skb->data - skb->nh.raw;
+ cleared_hlen = hdr_len;
ah = (struct ipv6_auth_hdr*)skb->data;
ahp = x->data;
nexthdr = ah->nexthdr;
@@ -297,27 +304,22 @@ int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu
if (!pskb_may_pull(skb, ah_hlen))
goto out;
- /* We are going to _remove_ AH header to keep sockets happy,
- * so... Later this can change. */
- if (skb_cloned(skb) &&
- pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
- goto out;
-
tmp_hdr = kmalloc(cleared_hlen, GFP_ATOMIC);
if (!tmp_hdr)
goto out;
memcpy(tmp_hdr, skb->nh.raw, cleared_hlen);
ipv6_clear_mutable_options(skb, &nh_offset, XFRM_POLICY_IN);
- iph->priority = 0;
- iph->flow_lbl[0] = 0;
- iph->flow_lbl[1] = 0;
- iph->flow_lbl[2] = 0;
- iph->hop_limit = 0;
+ skb->nh.ipv6h->priority = 0;
+ skb->nh.ipv6h->flow_lbl[0] = 0;
+ skb->nh.ipv6h->flow_lbl[1] = 0;
+ skb->nh.ipv6h->flow_lbl[2] = 0;
+ skb->nh.ipv6h->hop_limit = 0;
{
u8 auth_data[ahp->icv_trunc_len];
memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len);
+ memset(ah->auth_data, 0, ahp->icv_trunc_len);
skb_push(skb, skb->data - skb->nh.raw);
ahp->icv(ahp, skb, ah->auth_data);
if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) {