summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustin M. Forbes <jforbes@fedoraproject.org>2017-04-11 15:12:58 -0500
committerJustin M. Forbes <jforbes@fedoraproject.org>2017-04-11 15:12:58 -0500
commit21d113f3e9b99d4899686a091325e535d0ef8647 (patch)
tree19926b0a48cfbb16012f5c4baadd3fb5cd2dee9a
parent1b724fad468730d0d0281c937e99a3cde2d176da (diff)
downloadkernel-21d113f3e9b99d4899686a091325e535d0ef8647.tar.gz
kernel-21d113f3e9b99d4899686a091325e535d0ef8647.tar.xz
kernel-21d113f3e9b99d4899686a091325e535d0ef8647.zip
Fix CVE-2017-7308 and CVE-2017-7618
-rw-r--r--CVE-2017-7308.patch107
-rw-r--r--CVE-2017-7618.patch254
-rw-r--r--baseconfig/arm/CONFIG_HAMRADIO1
-rw-r--r--kernel-aarch64-debug.config2
-rw-r--r--kernel-aarch64.config2
-rw-r--r--kernel-armv7hl-debug.config2
-rw-r--r--kernel-armv7hl-lpae-debug.config2
-rw-r--r--kernel-armv7hl-lpae.config2
-rw-r--r--kernel-armv7hl.config2
-rw-r--r--kernel.spec11
10 files changed, 378 insertions, 7 deletions
diff --git a/CVE-2017-7308.patch b/CVE-2017-7308.patch
new file mode 100644
index 000000000..c257f9564
--- /dev/null
+++ b/CVE-2017-7308.patch
@@ -0,0 +1,107 @@
+From 2b6867c2ce76c596676bec7d2d525af525fdc6e2 Mon Sep 17 00:00:00 2001
+From: Andrey Konovalov <andreyknvl@google.com>
+Date: Wed, 29 Mar 2017 16:11:20 +0200
+Subject: [PATCH] net/packet: fix overflow in check for priv area size
+
+Subtracting tp_sizeof_priv from tp_block_size and casting to int
+to check whether one is less then the other doesn't always work
+(both of them are unsigned ints).
+
+Compare them as is instead.
+
+Also cast tp_sizeof_priv to u64 before using BLK_PLUS_PRIV, as
+it can overflow inside BLK_PLUS_PRIV otherwise.
+
+Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ net/packet/af_packet.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index a0dbe7c..2323ee3 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -4193,8 +4193,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
+ if (unlikely(!PAGE_ALIGNED(req->tp_block_size)))
+ goto out;
+ if (po->tp_version >= TPACKET_V3 &&
+- (int)(req->tp_block_size -
+- BLK_PLUS_PRIV(req_u->req3.tp_sizeof_priv)) <= 0)
++ req->tp_block_size <=
++ BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv))
+ goto out;
+ if (unlikely(req->tp_frame_size < po->tp_hdrlen +
+ po->tp_reserve))
+--
+2.9.3
+
+From 8f8d28e4d6d815a391285e121c3a53a0b6cb9e7b Mon Sep 17 00:00:00 2001
+From: Andrey Konovalov <andreyknvl@google.com>
+Date: Wed, 29 Mar 2017 16:11:21 +0200
+Subject: [PATCH] net/packet: fix overflow in check for tp_frame_nr
+
+When calculating rb->frames_per_block * req->tp_block_nr the result
+can overflow.
+
+Add a check that tp_block_size * tp_block_nr <= UINT_MAX.
+
+Since frames_per_block <= tp_block_size, the expression would
+never overflow.
+
+Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ net/packet/af_packet.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index 2323ee3..3ac286e 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -4205,6 +4205,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
+ rb->frames_per_block = req->tp_block_size / req->tp_frame_size;
+ if (unlikely(rb->frames_per_block == 0))
+ goto out;
++ if (unlikely(req->tp_block_size > UINT_MAX / req->tp_block_nr))
++ goto out;
+ if (unlikely((rb->frames_per_block * req->tp_block_nr) !=
+ req->tp_frame_nr))
+ goto out;
+--
+2.9.3
+
+From bcc5364bdcfe131e6379363f089e7b4108d35b70 Mon Sep 17 00:00:00 2001
+From: Andrey Konovalov <andreyknvl@google.com>
+Date: Wed, 29 Mar 2017 16:11:22 +0200
+Subject: [PATCH] net/packet: fix overflow in check for tp_reserve
+
+When calculating po->tp_hdrlen + po->tp_reserve the result can overflow.
+
+Fix by checking that tp_reserve <= INT_MAX on assign.
+
+Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ net/packet/af_packet.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index 3ac286e..8489bef 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -3665,6 +3665,8 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
+ return -EBUSY;
+ if (copy_from_user(&val, optval, sizeof(val)))
+ return -EFAULT;
++ if (val > INT_MAX)
++ return -EINVAL;
+ po->tp_reserve = val;
+ return 0;
+ }
+--
+2.9.3
+
diff --git a/CVE-2017-7618.patch b/CVE-2017-7618.patch
new file mode 100644
index 000000000..4e06b1d9a
--- /dev/null
+++ b/CVE-2017-7618.patch
@@ -0,0 +1,254 @@
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: 2017-04-10 9:27:57
+Subject: [PATCH v2] crypto: ahash - Fix EINPROGRESS notification callback
+
+On Mon, Apr 10, 2017 at 11:21:27AM +0200, Sabrina Dubroca wrote:
+>
+> > Cc: <vger@stable.kernel.org>
+>
+> Should that be stable@vger.kernel.org?
+
+Oops :)
+
+> > Reported-by: Sabrina Dubroca <sdubroca@redhat.com>
+> > Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+>
+> The definition of ahash_request_flags() was missing, so I added:
+>
+> static inline u32 ahash_request_flags(struct ahash_request *req)
+> {
+> return req->base.flags;
+> }
+>
+> And with this, my tests seem fine.
+>
+> Tested-by: Sabrina Dubroca <sd@queasysnail.net>
+> Could also you change the 'Reported-by:' to that email address?
+
+OK, here is v2.
+
+---8<---
+The ahash API modifies the request's callback function in order
+to clean up after itself in some corner cases (unaligned final
+and missing finup).
+
+When the request is complete ahash will restore the original
+callback and everything is fine. However, when the request gets
+an EBUSY on a full queue, an EINPROGRESS callback is made while
+the request is still ongoing.
+
+In this case the ahash API will incorrectly call its own callback.
+
+This patch fixes the problem by creating a temporary request
+object on the stack which is used to relay EINPROGRESS back to
+the original completion function.
+
+This patch also adds code to preserve the original flags value.
+
+Fixes: ab6bf4e5e5e4 ("crypto: hash - Fix the pointer voodoo in...")
+Cc: <stable@vger.kernel.org>
+Reported-by: Sabrina Dubroca <sd@queasysnail.net>
+Tested-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+
+diff --git a/crypto/ahash.c b/crypto/ahash.c
+index e58c497..1810feb 100644
+--- a/crypto/ahash.c
++++ b/crypto/ahash.c
+@@ -32,6 +32,7 @@ struct ahash_request_priv {
+ crypto_completion_t complete;
+ void *data;
+ u8 *result;
++ u32 flags;
+ void *ubuf[] CRYPTO_MINALIGN_ATTR;
+ };
+
+@@ -253,6 +254,8 @@ static int ahash_save_req(struct ahash_request *req, crypto_completion_t cplt)
+ priv->result = req->result;
+ priv->complete = req->base.complete;
+ priv->data = req->base.data;
++ priv->flags = req->base.flags;
++
+ /*
+ * WARNING: We do not backup req->priv here! The req->priv
+ * is for internal use of the Crypto API and the
+@@ -267,38 +270,44 @@ static int ahash_save_req(struct ahash_request *req, crypto_completion_t cplt)
+ return 0;
+ }
+
+-static void ahash_restore_req(struct ahash_request *req)
++static void ahash_restore_req(struct ahash_request *req, int err)
+ {
+ struct ahash_request_priv *priv = req->priv;
+
++ if (!err)
++ memcpy(priv->result, req->result,
++ crypto_ahash_digestsize(crypto_ahash_reqtfm(req)));
++
+ /* Restore the original crypto request. */
+ req->result = priv->result;
+- req->base.complete = priv->complete;
+- req->base.data = priv->data;
++
++ ahash_request_set_callback(req, priv->flags,
++ priv->complete, priv->data);
+ req->priv = NULL;
+
+ /* Free the req->priv.priv from the ADJUSTED request. */
+ kzfree(priv);
+ }
+
+-static void ahash_op_unaligned_finish(struct ahash_request *req, int err)
++static void ahash_notify_einprogress(struct ahash_request *req)
+ {
+ struct ahash_request_priv *priv = req->priv;
++ struct crypto_async_request oreq;
+
+- if (err == -EINPROGRESS)
+- return;
++ oreq.data = priv->data;
+
+- if (!err)
+- memcpy(priv->result, req->result,
+- crypto_ahash_digestsize(crypto_ahash_reqtfm(req)));
+-
+- ahash_restore_req(req);
++ priv->complete(&oreq, -EINPROGRESS);
+ }
+
+ static void ahash_op_unaligned_done(struct crypto_async_request *req, int err)
+ {
+ struct ahash_request *areq = req->data;
+
++ if (err == -EINPROGRESS) {
++ ahash_notify_einprogress(areq);
++ return;
++ }
++
+ /*
+ * Restore the original request, see ahash_op_unaligned() for what
+ * goes where.
+@@ -309,7 +318,7 @@ static void ahash_op_unaligned_done(struct crypto_async_request *req, int err)
+ */
+
+ /* First copy req->result into req->priv.result */
+- ahash_op_unaligned_finish(areq, err);
++ ahash_restore_req(areq, err);
+
+ /* Complete the ORIGINAL request. */
+ areq->base.complete(&areq->base, err);
+@@ -325,7 +334,12 @@ static int ahash_op_unaligned(struct ahash_request *req,
+ return err;
+
+ err = op(req);
+- ahash_op_unaligned_finish(req, err);
++ if (err == -EINPROGRESS ||
++ (err == -EBUSY && (ahash_request_flags(req) &
++ CRYPTO_TFM_REQ_MAY_BACKLOG)))
++ return err;
++
++ ahash_restore_req(req, err);
+
+ return err;
+ }
+@@ -360,25 +374,14 @@ int crypto_ahash_digest(struct ahash_request *req)
+ }
+ EXPORT_SYMBOL_GPL(crypto_ahash_digest);
+
+-static void ahash_def_finup_finish2(struct ahash_request *req, int err)
++static void ahash_def_finup_done2(struct crypto_async_request *req, int err)
+ {
+- struct ahash_request_priv *priv = req->priv;
++ struct ahash_request *areq = req->data;
+
+ if (err == -EINPROGRESS)
+ return;
+
+- if (!err)
+- memcpy(priv->result, req->result,
+- crypto_ahash_digestsize(crypto_ahash_reqtfm(req)));
+-
+- ahash_restore_req(req);
+-}
+-
+-static void ahash_def_finup_done2(struct crypto_async_request *req, int err)
+-{
+- struct ahash_request *areq = req->data;
+-
+- ahash_def_finup_finish2(areq, err);
++ ahash_restore_req(areq, err);
+
+ areq->base.complete(&areq->base, err);
+ }
+@@ -389,11 +392,15 @@ static int ahash_def_finup_finish1(struct ahash_request *req, int err)
+ goto out;
+
+ req->base.complete = ahash_def_finup_done2;
+- req->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
++
+ err = crypto_ahash_reqtfm(req)->final(req);
++ if (err == -EINPROGRESS ||
++ (err == -EBUSY && (ahash_request_flags(req) &
++ CRYPTO_TFM_REQ_MAY_BACKLOG)))
++ return err;
+
+ out:
+- ahash_def_finup_finish2(req, err);
++ ahash_restore_req(req, err);
+ return err;
+ }
+
+@@ -401,7 +408,16 @@ static void ahash_def_finup_done1(struct crypto_async_request *req, int err)
+ {
+ struct ahash_request *areq = req->data;
+
++ if (err == -EINPROGRESS) {
++ ahash_notify_einprogress(areq);
++ return;
++ }
++
++ areq->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
++
+ err = ahash_def_finup_finish1(areq, err);
++ if (areq->priv)
++ return;
+
+ areq->base.complete(&areq->base, err);
+ }
+@@ -416,6 +432,11 @@ static int ahash_def_finup(struct ahash_request *req)
+ return err;
+
+ err = tfm->update(req);
++ if (err == -EINPROGRESS ||
++ (err == -EBUSY && (ahash_request_flags(req) &
++ CRYPTO_TFM_REQ_MAY_BACKLOG)))
++ return err;
++
+ return ahash_def_finup_finish1(req, err);
+ }
+
+diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h
+index 1d4f365..f6d9af3e 100644
+--- a/include/crypto/internal/hash.h
++++ b/include/crypto/internal/hash.h
+@@ -166,6 +166,16 @@ static inline struct ahash_instance *ahash_alloc_instance(
+ return crypto_alloc_instance2(name, alg, ahash_instance_headroom());
+ }
+
++static inline void ahash_request_complete(struct ahash_request *req, int err)
++{
++ req->base.complete(&req->base, err);
++}
++
++static inline u32 ahash_request_flags(struct ahash_request *req)
++{
++ return req->base.flags;
++}
++
+ static inline struct crypto_ahash *crypto_spawn_ahash(
+ struct crypto_ahash_spawn *spawn)
+ {
+--
+Email: Herbert Xu <herbert@gondor.apana.org.au>
+Home Page: http://gondor.apana.org.au/~herbert/
+PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
diff --git a/baseconfig/arm/CONFIG_HAMRADIO b/baseconfig/arm/CONFIG_HAMRADIO
deleted file mode 100644
index 477ae40db..000000000
--- a/baseconfig/arm/CONFIG_HAMRADIO
+++ /dev/null
@@ -1 +0,0 @@
-# CONFIG_HAMRADIO is not set
diff --git a/kernel-aarch64-debug.config b/kernel-aarch64-debug.config
index 819c50e8a..7f084c7c2 100644
--- a/kernel-aarch64-debug.config
+++ b/kernel-aarch64-debug.config
@@ -1707,7 +1707,7 @@ CONFIG_GREENASIA_FF=y
# CONFIG_GS_FPGABOOT is not set
CONFIG_GTP=m
CONFIG_HAMACHI=m
-# CONFIG_HAMRADIO is not set
+CONFIG_HAMRADIO=y
CONFIG_HANGCHECK_TIMER=m
CONFIG_HAPPYMEAL=m
CONFIG_HARDENED_USERCOPY=y
diff --git a/kernel-aarch64.config b/kernel-aarch64.config
index a47228fd8..8af5c11d0 100644
--- a/kernel-aarch64.config
+++ b/kernel-aarch64.config
@@ -1690,7 +1690,7 @@ CONFIG_GREENASIA_FF=y
# CONFIG_GS_FPGABOOT is not set
CONFIG_GTP=m
CONFIG_HAMACHI=m
-# CONFIG_HAMRADIO is not set
+CONFIG_HAMRADIO=y
CONFIG_HANGCHECK_TIMER=m
CONFIG_HAPPYMEAL=m
CONFIG_HARDENED_USERCOPY=y
diff --git a/kernel-armv7hl-debug.config b/kernel-armv7hl-debug.config
index ffadf9aea..12c8a4f20 100644
--- a/kernel-armv7hl-debug.config
+++ b/kernel-armv7hl-debug.config
@@ -1865,7 +1865,7 @@ CONFIG_GREENASIA_FF=y
CONFIG_GS_FPGABOOT=m
CONFIG_GTP=m
CONFIG_HAMACHI=m
-# CONFIG_HAMRADIO is not set
+CONFIG_HAMRADIO=y
CONFIG_HANGCHECK_TIMER=m
CONFIG_HAPPYMEAL=m
CONFIG_HARDENED_USERCOPY=y
diff --git a/kernel-armv7hl-lpae-debug.config b/kernel-armv7hl-lpae-debug.config
index dc6d68dcc..04c6d88f1 100644
--- a/kernel-armv7hl-lpae-debug.config
+++ b/kernel-armv7hl-lpae-debug.config
@@ -1774,7 +1774,7 @@ CONFIG_GREENASIA_FF=y
# CONFIG_GS_FPGABOOT is not set
CONFIG_GTP=m
CONFIG_HAMACHI=m
-# CONFIG_HAMRADIO is not set
+CONFIG_HAMRADIO=y
CONFIG_HANGCHECK_TIMER=m
CONFIG_HAPPYMEAL=m
CONFIG_HARDENED_USERCOPY=y
diff --git a/kernel-armv7hl-lpae.config b/kernel-armv7hl-lpae.config
index 1d2fa42ef..493546405 100644
--- a/kernel-armv7hl-lpae.config
+++ b/kernel-armv7hl-lpae.config
@@ -1758,7 +1758,7 @@ CONFIG_GREENASIA_FF=y
# CONFIG_GS_FPGABOOT is not set
CONFIG_GTP=m
CONFIG_HAMACHI=m
-# CONFIG_HAMRADIO is not set
+CONFIG_HAMRADIO=y
CONFIG_HANGCHECK_TIMER=m
CONFIG_HAPPYMEAL=m
CONFIG_HARDENED_USERCOPY=y
diff --git a/kernel-armv7hl.config b/kernel-armv7hl.config
index 1aa3356e9..ca72b40df 100644
--- a/kernel-armv7hl.config
+++ b/kernel-armv7hl.config
@@ -1849,7 +1849,7 @@ CONFIG_GREENASIA_FF=y
CONFIG_GS_FPGABOOT=m
CONFIG_GTP=m
CONFIG_HAMACHI=m
-# CONFIG_HAMRADIO is not set
+CONFIG_HAMRADIO=y
CONFIG_HANGCHECK_TIMER=m
CONFIG_HAPPYMEAL=m
CONFIG_HARDENED_USERCOPY=y
diff --git a/kernel.spec b/kernel.spec
index 417f11b74..7e0527601 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -622,6 +622,12 @@ Patch862: 1-2-media-cxusb-Use-a-dma-capable-buffer-also-for-reading.patch
#rhbz 1441310
Patch863: rhbz_1441310.patch
+# CVE-2017-7618 rhbz 1441095 1441093
+Patch865: CVE-2017-7618.patch
+
+# CVE-2017-7308 rhbz 1437404 1437406
+Patch866: CVE-2017-7308.patch
+
# END OF PATCH DEFINITIONS
%endif
@@ -2191,6 +2197,11 @@ fi
#
#
%changelog
+* Tue Apr 11 2017 Justin M. Forbes <jforbes@fedoraproject.org>
+- Fix CVE-2017-7618 (rhbz 1441095 1441093)
+- Fix CVE-2017-7308 (rhbz 1437404 1437406)
+- Turn on CONFIG_HAMRADIO for arm (rhbz 1425990)
+
* Tue Apr 11 2017 Laura Abbott <labbott@fedoraproject.org>
- Fix for openshift networking (rhbz 1441310)