aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/ah4.c14
-rw-r--r--net/ipv4/esp4.c24
2 files changed, 25 insertions, 13 deletions
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index a989d29b44ea..d76803a3dcae 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -169,6 +169,8 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
169 if (ip_clear_mutable_options(iph, &dummy)) 169 if (ip_clear_mutable_options(iph, &dummy))
170 goto out; 170 goto out;
171 } 171 }
172
173 spin_lock(&x->lock);
172 { 174 {
173 u8 auth_data[MAX_AH_AUTH_LEN]; 175 u8 auth_data[MAX_AH_AUTH_LEN];
174 176
@@ -176,12 +178,16 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
176 skb_push(skb, ihl); 178 skb_push(skb, ihl);
177 err = ah_mac_digest(ahp, skb, ah->auth_data); 179 err = ah_mac_digest(ahp, skb, ah->auth_data);
178 if (err) 180 if (err)
179 goto out; 181 goto unlock;
180 if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) { 182 if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len))
181 err = -EBADMSG; 183 err = -EBADMSG;
182 goto out;
183 }
184 } 184 }
185unlock:
186 spin_unlock(&x->lock);
187
188 if (err)
189 goto out;
190
185 skb->network_header += ah_hlen; 191 skb->network_header += ah_hlen;
186 memcpy(skb_network_header(skb), work_buf, ihl); 192 memcpy(skb_network_header(skb), work_buf, ihl);
187 skb->transport_header = skb->network_header; 193 skb->transport_header = skb->network_header;
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 3350a7d50669..28ea5c77ca23 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -171,29 +171,31 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
171 if (elen <= 0 || (elen & (blksize-1))) 171 if (elen <= 0 || (elen & (blksize-1)))
172 goto out; 172 goto out;
173 173
174 if ((err = skb_cow_data(skb, 0, &trailer)) < 0)
175 goto out;
176 nfrags = err;
177
178 skb->ip_summed = CHECKSUM_NONE;
179
180 spin_lock(&x->lock);
181
174 /* If integrity check is required, do this. */ 182 /* If integrity check is required, do this. */
175 if (esp->auth.icv_full_len) { 183 if (esp->auth.icv_full_len) {
176 u8 sum[alen]; 184 u8 sum[alen];
177 185
178 err = esp_mac_digest(esp, skb, 0, skb->len - alen); 186 err = esp_mac_digest(esp, skb, 0, skb->len - alen);
179 if (err) 187 if (err)
180 goto out; 188 goto unlock;
181 189
182 if (skb_copy_bits(skb, skb->len - alen, sum, alen)) 190 if (skb_copy_bits(skb, skb->len - alen, sum, alen))
183 BUG(); 191 BUG();
184 192
185 if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) { 193 if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
186 err = -EBADMSG; 194 err = -EBADMSG;
187 goto out; 195 goto unlock;
188 } 196 }
189 } 197 }
190 198
191 if ((err = skb_cow_data(skb, 0, &trailer)) < 0)
192 goto out;
193 nfrags = err;
194
195 skb->ip_summed = CHECKSUM_NONE;
196
197 esph = (struct ip_esp_hdr *)skb->data; 199 esph = (struct ip_esp_hdr *)skb->data;
198 200
199 /* Get ivec. This can be wrong, check against another impls. */ 201 /* Get ivec. This can be wrong, check against another impls. */
@@ -206,7 +208,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
206 err = -ENOMEM; 208 err = -ENOMEM;
207 sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); 209 sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
208 if (!sg) 210 if (!sg)
209 goto out; 211 goto unlock;
210 } 212 }
211 sg_init_table(sg, nfrags); 213 sg_init_table(sg, nfrags);
212 skb_to_sgvec(skb, sg, 214 skb_to_sgvec(skb, sg,
@@ -215,6 +217,10 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
215 err = crypto_blkcipher_decrypt(&desc, sg, sg, elen); 217 err = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
216 if (unlikely(sg != &esp->sgbuf[0])) 218 if (unlikely(sg != &esp->sgbuf[0]))
217 kfree(sg); 219 kfree(sg);
220
221unlock:
222 spin_unlock(&x->lock);
223
218 if (unlikely(err)) 224 if (unlikely(err))
219 goto out; 225 goto out;
220 226