From 6771be113806a762fae4a6c3ca0ad3d5d1ef303e Mon Sep 17 00:00:00 2001 From: Salvatore Bonaccorso Date: Thu, 27 Apr 2017 07:40:44 +0200 Subject: [PATCH] macsec: dynamically allocate space for sglist --- debian/changelog | 1 + ...ynamically-allocate-space-for-sglist.patch | 117 ++++++++++++++++++ debian/patches/series | 1 + 3 files changed, 119 insertions(+) create mode 100644 debian/patches/bugfix/all/macsec-dynamically-allocate-space-for-sglist.patch diff --git a/debian/changelog b/debian/changelog index d9552c1ef..8465536ca 100644 --- a/debian/changelog +++ b/debian/changelog @@ -347,6 +347,7 @@ linux (4.9.24-1) UNRELEASED; urgency=medium [ Salvatore Bonaccorso ] * ping: implement proper locking (CVE-2017-2671) * macsec: avoid heap overflow in skb_to_sgvec (CVE-2017-7477) + * macsec: dynamically allocate space for sglist [ Aurelien Jarno ] * [mips*/octeon] Drop obsolete patch adding support for the UBNT E200 diff --git a/debian/patches/bugfix/all/macsec-dynamically-allocate-space-for-sglist.patch b/debian/patches/bugfix/all/macsec-dynamically-allocate-space-for-sglist.patch new file mode 100644 index 000000000..da947b78a --- /dev/null +++ b/debian/patches/bugfix/all/macsec-dynamically-allocate-space-for-sglist.patch @@ -0,0 +1,117 @@ +From: "Jason A. Donenfeld" +Date: Tue, 25 Apr 2017 19:08:18 +0200 +Subject: macsec: dynamically allocate space for sglist +Origin: https://git.kernel.org/linus/5294b83086cc1c35b4efeca03644cf9d12282e5b + +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 +Acked-by: Sabrina Dubroca +Signed-off-by: David S. Miller +--- + drivers/net/macsec.c | 29 ++++++++++++++++++++++------- + 1 file changed, 22 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c +index dbab05a..49ce4e9 100644 +--- a/drivers/net/macsec.c ++++ b/drivers/net/macsec.c +@@ -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, + unsigned char **iv, +- struct scatterlist **sg) ++ struct scatterlist **sg, ++ int num_frags) + { + size_t size, iv_offset, sg_offset; + struct aead_request *req; +@@ -629,7 +630,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; + + tmp = kmalloc(size, GFP_ATOMIC); + if (!tmp) +@@ -649,6 +650,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb, + { + int ret; + struct scatterlist *sg; ++ struct sk_buff *trailer; + unsigned char *iv; + struct ethhdr *eth; + struct macsec_eth_header *hh; +@@ -723,7 +725,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); ++ 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) { + macsec_txsa_put(tx_sa); + kfree_skb(skb); +@@ -732,7 +741,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb, + + 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); + + if (tx_sc->encrypt) { +@@ -917,6 +926,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, + { + int ret; + struct scatterlist *sg; ++ struct sk_buff *trailer; + unsigned char *iv; + struct aead_request *req; + struct macsec_eth_header *hdr; +@@ -927,7 +937,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); ++ 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) { + kfree_skb(skb); + return ERR_PTR(-ENOMEM); +@@ -936,7 +951,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) { +@@ -2716,7 +2731,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 struct lock_class_key macsec_netdev_addr_lock_key; + + static int macsec_dev_init(struct net_device *dev) +-- +2.1.4 + diff --git a/debian/patches/series b/debian/patches/series index ca0b6f56a..47b1db787 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -111,6 +111,7 @@ bugfix/all/ping-implement-proper-locking.patch bugfix/all/keys-disallow-keyrings-beginning-with-.-to-be-joined.patch bugfix/all/keys-fix-keyctl_set_reqkey_keyring-to-not-leak-threa.patch bugfix/all/macsec-avoid-heap-overflow-in-skb_to_sgvec.patch +bugfix/all/macsec-dynamically-allocate-space-for-sglist.patch # Fix exported symbol versions bugfix/ia64/revert-ia64-move-exports-to-definitions.patch