Commit 61266d5f authored by David S. Miller's avatar David S. Miller

[IPSEC]: In ESP, do not put scatterlist array on stack.

Put it in per-esp data instead.  Noticed by Linus.
Signed-off-by: default avatarDavid S. Miller <davem@redhat.com>
parent b4321277
......@@ -2,9 +2,14 @@
#define _NET_ESP_H
#include <net/xfrm.h>
#include <asm/scatterlist.h>
#define ESP_NUM_FAST_SG 4
struct esp_data
{
struct scatterlist sgbuf[ESP_NUM_FAST_SG];
/* Confidentiality */
struct {
u8 *key; /* Key */
......
......@@ -11,8 +11,6 @@
#include <net/icmp.h>
#include <net/udp.h>
#define MAX_SG_ONSTACK 4
/* decapsulation data for use when post-processing */
struct esp_decap_data {
xfrm_address_t saddr;
......@@ -185,17 +183,16 @@ int esp_output(struct sk_buff **pskb)
crypto_cipher_set_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm));
do {
struct scatterlist sgbuf[nfrags>MAX_SG_ONSTACK ? 0 : nfrags];
struct scatterlist *sg = sgbuf;
struct scatterlist *sg = &esp->sgbuf[0];
if (unlikely(nfrags > MAX_SG_ONSTACK)) {
if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
if (!sg)
goto error;
}
skb_to_sgvec(*pskb, sg, esph->enc_data+esp->conf.ivlen-(*pskb)->data, clen);
crypto_cipher_encrypt(tfm, sg, sg, clen);
if (unlikely(sg != sgbuf))
if (unlikely(sg != &esp->sgbuf[0]))
kfree(sg);
} while (0);
......@@ -283,19 +280,18 @@ int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_bu
{
u8 nexthdr[2];
struct scatterlist sgbuf[nfrags>MAX_SG_ONSTACK ? 0 : nfrags];
struct scatterlist *sg = sgbuf;
struct scatterlist *sg = &esp->sgbuf[0];
u8 workbuf[60];
int padlen;
if (unlikely(nfrags > MAX_SG_ONSTACK)) {
if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
if (!sg)
goto out;
}
skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen);
crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen);
if (unlikely(sg != sgbuf))
if (unlikely(sg != &esp->sgbuf[0]))
kfree(sg);
if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
......
......@@ -38,8 +38,6 @@
#include <net/ipv6.h>
#include <linux/icmpv6.h>
#define MAX_SG_ONSTACK 4
int esp6_output(struct sk_buff **pskb)
{
int err;
......@@ -151,17 +149,16 @@ int esp6_output(struct sk_buff **pskb)
crypto_cipher_set_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm));
do {
struct scatterlist sgbuf[nfrags>MAX_SG_ONSTACK ? 0 : nfrags];
struct scatterlist *sg = sgbuf;
struct scatterlist *sg = &esp->sgbuf[0];
if (unlikely(nfrags > MAX_SG_ONSTACK)) {
if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
if (!sg)
goto error;
}
skb_to_sgvec(*pskb, sg, esph->enc_data+esp->conf.ivlen-(*pskb)->data, clen);
crypto_cipher_encrypt(tfm, sg, sg, clen);
if (unlikely(sg != sgbuf))
if (unlikely(sg != &esp->sgbuf[0]))
kfree(sg);
} while (0);
......@@ -259,12 +256,11 @@ int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_b
{
u8 nexthdr[2];
struct scatterlist sgbuf[nfrags>MAX_SG_ONSTACK ? 0 : nfrags];
struct scatterlist *sg = sgbuf;
struct scatterlist *sg = &esp->sgbuf[0];
u8 padlen;
u8 *prevhdr;
if (unlikely(nfrags > MAX_SG_ONSTACK)) {
if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
if (!sg) {
ret = -ENOMEM;
......@@ -273,7 +269,7 @@ int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_b
}
skb_to_sgvec(skb, sg, sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen, elen);
crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen);
if (unlikely(sg != sgbuf))
if (unlikely(sg != &esp->sgbuf[0]))
kfree(sg);
if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment