]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
macsec: dynamically allocate space for sglist v4.1.12-105.0.20170705_2000
authorJason A. Donenfeld <Jason@zx2c4.com>
Tue, 25 Apr 2017 17:08:18 +0000 (19:08 +0200)
committerChuck Anderson <chuck.anderson@oracle.com>
Thu, 6 Jul 2017 03:49:18 +0000 (20:49 -0700)
Orabug: 25953290
CVE: CVE-2017-7477

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: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver")
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Acked-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 5294b83086cc1c35b4efeca03644cf9d12282e5b)
Signed-off-by: Brian Maly <brian.maly@oracle.com>
Conflicts:
drivers/net/macsec.c

drivers/net/macsec.c

index 5cdb39beb180470134805225cdadca5b6f47a076..b1b1ff0121885989a8f9bd3144aa5ae0cdbbee6d 100644 (file)
@@ -608,7 +608,8 @@ static void macsec_encrypt_done(struct crypto_async_request *base, int err)
 static struct aead_request *macsec_alloc_req(struct crypto_aead *tfm,
                                             unsigned char **iv,
                                              struct scatterlist **sg,
-                                             struct scatterlist **sg_ad)
+                                             struct scatterlist **sg_ad,
+                                                                                        int num_frags)
 {
        size_t size, iv_offset, sg_offset, sg_ad_offset;
        struct aead_request *req;
@@ -620,7 +621,7 @@ static struct aead_request *macsec_alloc_req(struct crypto_aead *tfm,
 
        size = ALIGN(size, __alignof__(struct scatterlist));
        sg_offset = size;
-       size += sizeof(struct scatterlist) * (MAX_SKB_FRAGS + 1);
+       size += sizeof(struct scatterlist) * num_frags;
 
        size = ALIGN(size, __alignof__(struct scatterlist));
        sg_ad_offset = size;
@@ -646,6 +647,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
        int ret;
        struct scatterlist *sg;
        struct scatterlist *sg_ad;
+       struct sk_buff *trailer;
        unsigned char *iv;
        struct ethhdr *eth;
        struct macsec_eth_header *hh;
@@ -718,7 +720,14 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
                return ERR_PTR(-EINVAL);
        }
 
-       req = macsec_alloc_req(tx_sa->key.tfm, &iv, &sg, &sg_ad);
+       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, &sg_ad, ret);
        if (!req) {
                macsec_txsa_put(tx_sa);
                kfree_skb(skb);
@@ -727,6 +736,8 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
 
        macsec_fill_iv(iv, secy->sci, pn);
 
+       sg_init_table(sg, ret);
+       
        if (tx_sc->encrypt) {
                int assoc_len = macsec_hdr_len(tx_sc->send_sci);
                 int data_len = skb->len - secy->icv_len - assoc_len;
@@ -921,6 +932,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
        int ret;
        struct scatterlist *sg;
        struct scatterlist *sg_ad;
+       struct sk_buff *trailer;
        unsigned char *iv;
        struct aead_request *req;
        struct macsec_eth_header *hdr;
@@ -931,7 +943,12 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
        if (!skb)
                return ERR_PTR(-ENOMEM);
 
-       req = macsec_alloc_req(rx_sa->key.tfm, &iv, &sg, &sg_ad);
+       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, &sg_ad, ret);
        if (!req) {
                kfree_skb(skb);
                return ERR_PTR(-ENOMEM);
@@ -940,7 +957,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
        hdr = (struct macsec_eth_header *)skb->data;
        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);
 
        if (hdr->tci_an & MACSEC_TCI_E) {
@@ -2680,7 +2697,7 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
 }
 
 #define MACSEC_FEATURES \
-       (NETIF_F_SG | NETIF_F_HIGHDMA)
+       (NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST)
 static int macsec_dev_init(struct net_device *dev)
 {
        struct macsec_dev *macsec = macsec_priv(dev);