Commit 5294b830 authored by Jason A. Donenfeld's avatar Jason A. Donenfeld Committed by David S. Miller

macsec: dynamically allocate space for sglist

We call skb_cow_data, which is good anyway to ensure we can actually
modify the skb as such (another error from prior). Now that we have the
number of fragments required, we can safely allocate exactly that amount
of memory.

Fixes: c09440f7 ("macsec: introduce IEEE 802.1AE driver")
Signed-off-by: default avatarJason A. Donenfeld <Jason@zx2c4.com>
Acked-by: default avatarSabrina Dubroca <sd@queasysnail.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b43bd728
...@@ -617,7 +617,8 @@ static void macsec_encrypt_done(struct crypto_async_request *base, int err) ...@@ -617,7 +617,8 @@ static void macsec_encrypt_done(struct crypto_async_request *base, int err)
static struct aead_request *macsec_alloc_req(struct crypto_aead *tfm, static struct aead_request *macsec_alloc_req(struct crypto_aead *tfm,
unsigned char **iv, unsigned char **iv,
struct scatterlist **sg) struct scatterlist **sg,
int num_frags)
{ {
size_t size, iv_offset, sg_offset; size_t size, iv_offset, sg_offset;
struct aead_request *req; struct aead_request *req;
...@@ -629,7 +630,7 @@ static struct aead_request *macsec_alloc_req(struct crypto_aead *tfm, ...@@ -629,7 +630,7 @@ static struct aead_request *macsec_alloc_req(struct crypto_aead *tfm,
size = ALIGN(size, __alignof__(struct scatterlist)); size = ALIGN(size, __alignof__(struct scatterlist));
sg_offset = size; sg_offset = size;
size += sizeof(struct scatterlist) * (MAX_SKB_FRAGS + 1); size += sizeof(struct scatterlist) * num_frags;
tmp = kmalloc(size, GFP_ATOMIC); tmp = kmalloc(size, GFP_ATOMIC);
if (!tmp) if (!tmp)
...@@ -649,6 +650,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb, ...@@ -649,6 +650,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
{ {
int ret; int ret;
struct scatterlist *sg; struct scatterlist *sg;
struct sk_buff *trailer;
unsigned char *iv; unsigned char *iv;
struct ethhdr *eth; struct ethhdr *eth;
struct macsec_eth_header *hh; struct macsec_eth_header *hh;
...@@ -723,7 +725,14 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb, ...@@ -723,7 +725,14 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
req = macsec_alloc_req(tx_sa->key.tfm, &iv, &sg); ret = skb_cow_data(skb, 0, &trailer);
if (unlikely(ret < 0)) {
macsec_txsa_put(tx_sa);
kfree_skb(skb);
return ERR_PTR(ret);
}
req = macsec_alloc_req(tx_sa->key.tfm, &iv, &sg, ret);
if (!req) { if (!req) {
macsec_txsa_put(tx_sa); macsec_txsa_put(tx_sa);
kfree_skb(skb); kfree_skb(skb);
...@@ -732,7 +741,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb, ...@@ -732,7 +741,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
macsec_fill_iv(iv, secy->sci, pn); macsec_fill_iv(iv, secy->sci, pn);
sg_init_table(sg, MAX_SKB_FRAGS + 1); sg_init_table(sg, ret);
skb_to_sgvec(skb, sg, 0, skb->len); skb_to_sgvec(skb, sg, 0, skb->len);
if (tx_sc->encrypt) { if (tx_sc->encrypt) {
...@@ -917,6 +926,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, ...@@ -917,6 +926,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
{ {
int ret; int ret;
struct scatterlist *sg; struct scatterlist *sg;
struct sk_buff *trailer;
unsigned char *iv; unsigned char *iv;
struct aead_request *req; struct aead_request *req;
struct macsec_eth_header *hdr; struct macsec_eth_header *hdr;
...@@ -927,7 +937,12 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, ...@@ -927,7 +937,12 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
if (!skb) if (!skb)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
req = macsec_alloc_req(rx_sa->key.tfm, &iv, &sg); ret = skb_cow_data(skb, 0, &trailer);
if (unlikely(ret < 0)) {
kfree_skb(skb);
return ERR_PTR(ret);
}
req = macsec_alloc_req(rx_sa->key.tfm, &iv, &sg, ret);
if (!req) { if (!req) {
kfree_skb(skb); kfree_skb(skb);
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
...@@ -936,7 +951,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, ...@@ -936,7 +951,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
hdr = (struct macsec_eth_header *)skb->data; hdr = (struct macsec_eth_header *)skb->data;
macsec_fill_iv(iv, sci, ntohl(hdr->packet_number)); macsec_fill_iv(iv, sci, ntohl(hdr->packet_number));
sg_init_table(sg, MAX_SKB_FRAGS + 1); sg_init_table(sg, ret);
skb_to_sgvec(skb, sg, 0, skb->len); skb_to_sgvec(skb, sg, 0, skb->len);
if (hdr->tci_an & MACSEC_TCI_E) { if (hdr->tci_an & MACSEC_TCI_E) {
...@@ -2716,7 +2731,7 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb, ...@@ -2716,7 +2731,7 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
} }
#define MACSEC_FEATURES \ #define MACSEC_FEATURES \
(NETIF_F_SG | NETIF_F_HIGHDMA) (NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST)
static struct lock_class_key macsec_netdev_addr_lock_key; static struct lock_class_key macsec_netdev_addr_lock_key;
static int macsec_dev_init(struct net_device *dev) static int macsec_dev_init(struct net_device *dev)
......
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