aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/esp4.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/esp4.c')
-rw-r--r--net/ipv4/esp4.c24
1 files changed, 15 insertions, 9 deletions
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