]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 12 Jun 2017 07:42:58 +0000 (09:42 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 12 Jun 2017 07:42:58 +0000 (09:42 +0200)
added patches:
crypto-gcm-wait-for-crypto-op-not-signal-safe.patch
keys-fix-dereferencing-null-payload-with-nonzero-length.patch
keys-fix-freeing-uninitialized-memory-in-key_update.patch
nfsd4-fix-null-dereference-on-replay.patch

queue-3.18/crypto-gcm-wait-for-crypto-op-not-signal-safe.patch [new file with mode: 0644]
queue-3.18/keys-fix-dereferencing-null-payload-with-nonzero-length.patch [new file with mode: 0644]
queue-3.18/keys-fix-freeing-uninitialized-memory-in-key_update.patch [new file with mode: 0644]
queue-3.18/nfsd4-fix-null-dereference-on-replay.patch [new file with mode: 0644]
queue-3.18/series

diff --git a/queue-3.18/crypto-gcm-wait-for-crypto-op-not-signal-safe.patch b/queue-3.18/crypto-gcm-wait-for-crypto-op-not-signal-safe.patch
new file mode 100644 (file)
index 0000000..adb3cfa
--- /dev/null
@@ -0,0 +1,40 @@
+From f3ad587070d6bd961ab942b3fd7a85d00dfc934b Mon Sep 17 00:00:00 2001
+From: Gilad Ben-Yossef <gilad@benyossef.com>
+Date: Thu, 18 May 2017 16:29:25 +0300
+Subject: crypto: gcm - wait for crypto op not signal safe
+
+From: Gilad Ben-Yossef <gilad@benyossef.com>
+
+commit f3ad587070d6bd961ab942b3fd7a85d00dfc934b upstream.
+
+crypto_gcm_setkey() was using wait_for_completion_interruptible() to
+wait for completion of async crypto op but if a signal occurs it
+may return before DMA ops of HW crypto provider finish, thus
+corrupting the data buffer that is kfree'ed in this case.
+
+Resolve this by using wait_for_completion() instead.
+
+Reported-by: Eric Biggers <ebiggers3@gmail.com>
+Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/gcm.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/crypto/gcm.c
++++ b/crypto/gcm.c
+@@ -146,10 +146,8 @@ static int crypto_gcm_setkey(struct cryp
+       err = crypto_ablkcipher_encrypt(&data->req);
+       if (err == -EINPROGRESS || err == -EBUSY) {
+-              err = wait_for_completion_interruptible(
+-                      &data->result.completion);
+-              if (!err)
+-                      err = data->result.err;
++              wait_for_completion(&data->result.completion);
++              err = data->result.err;
+       }
+       if (err)
diff --git a/queue-3.18/keys-fix-dereferencing-null-payload-with-nonzero-length.patch b/queue-3.18/keys-fix-dereferencing-null-payload-with-nonzero-length.patch
new file mode 100644 (file)
index 0000000..0451185
--- /dev/null
@@ -0,0 +1,48 @@
+From 5649645d725c73df4302428ee4e02c869248b4c5 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Thu, 8 Jun 2017 14:48:40 +0100
+Subject: KEYS: fix dereferencing NULL payload with nonzero length
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit 5649645d725c73df4302428ee4e02c869248b4c5 upstream.
+
+sys_add_key() and the KEYCTL_UPDATE operation of sys_keyctl() allowed a
+NULL payload with nonzero length to be passed to the key type's
+->preparse(), ->instantiate(), and/or ->update() methods.  Various key
+types including asymmetric, cifs.idmap, cifs.spnego, and pkcs7_test did
+not handle this case, allowing an unprivileged user to trivially cause a
+NULL pointer dereference (kernel oops) if one of these key types was
+present.  Fix it by doing the copy_from_user() when 'plen' is nonzero
+rather than when '_payload' is non-NULL, causing the syscall to fail
+with EFAULT as expected when an invalid buffer is specified.
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: James Morris <james.l.morris@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/keys/keyctl.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/security/keys/keyctl.c
++++ b/security/keys/keyctl.c
+@@ -99,7 +99,7 @@ SYSCALL_DEFINE5(add_key, const char __us
+       payload = NULL;
+       vm = false;
+-      if (_payload) {
++      if (plen) {
+               ret = -ENOMEM;
+               payload = kmalloc(plen, GFP_KERNEL | __GFP_NOWARN);
+               if (!payload) {
+@@ -333,7 +333,7 @@ long keyctl_update_key(key_serial_t id,
+       /* pull the payload in if one was supplied */
+       payload = NULL;
+-      if (_payload) {
++      if (plen) {
+               ret = -ENOMEM;
+               payload = kmalloc(plen, GFP_KERNEL);
+               if (!payload)
diff --git a/queue-3.18/keys-fix-freeing-uninitialized-memory-in-key_update.patch b/queue-3.18/keys-fix-freeing-uninitialized-memory-in-key_update.patch
new file mode 100644 (file)
index 0000000..0d28385
--- /dev/null
@@ -0,0 +1,91 @@
+From 63a0b0509e700717a59f049ec6e4e04e903c7fe2 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Thu, 8 Jun 2017 14:48:47 +0100
+Subject: KEYS: fix freeing uninitialized memory in key_update()
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit 63a0b0509e700717a59f049ec6e4e04e903c7fe2 upstream.
+
+key_update() freed the key_preparsed_payload even if it was not
+initialized first.  This would cause a crash if userspace called
+keyctl_update() on a key with type like "asymmetric" that has a
+->preparse() method but not an ->update() method.  Possibly it could
+even be triggered for other key types by racing with keyctl_setperm() to
+make the KEY_NEED_WRITE check fail (the permission was already checked,
+so normally it wouldn't fail there).
+
+Reproducer with key type "asymmetric", given a valid cert.der:
+
+keyctl new_session
+keyid=$(keyctl padd asymmetric desc @s < cert.der)
+keyctl setperm $keyid 0x3f000000
+keyctl update $keyid data
+
+[  150.686666] BUG: unable to handle kernel NULL pointer dereference at 0000000000000001
+[  150.687601] IP: asymmetric_key_free_kids+0x12/0x30
+[  150.688139] PGD 38a3d067
+[  150.688141] PUD 3b3de067
+[  150.688447] PMD 0
+[  150.688745]
+[  150.689160] Oops: 0000 [#1] SMP
+[  150.689455] Modules linked in:
+[  150.689769] CPU: 1 PID: 2478 Comm: keyctl Not tainted 4.11.0-rc4-xfstests-00187-ga9f6b6b8cd2f #742
+[  150.690916] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-20170228_101828-anatol 04/01/2014
+[  150.692199] task: ffff88003b30c480 task.stack: ffffc90000350000
+[  150.692952] RIP: 0010:asymmetric_key_free_kids+0x12/0x30
+[  150.693556] RSP: 0018:ffffc90000353e58 EFLAGS: 00010202
+[  150.694142] RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000004
+[  150.694845] RDX: ffffffff81ee3920 RSI: ffff88003d4b0700 RDI: 0000000000000001
+[  150.697569] RBP: ffffc90000353e60 R08: ffff88003d5d2140 R09: 0000000000000000
+[  150.702483] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000001
+[  150.707393] R13: 0000000000000004 R14: ffff880038a4d2d8 R15: 000000000040411f
+[  150.709720] FS:  00007fcbcee35700(0000) GS:ffff88003fd00000(0000) knlGS:0000000000000000
+[  150.711504] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[  150.712733] CR2: 0000000000000001 CR3: 0000000039eab000 CR4: 00000000003406e0
+[  150.714487] Call Trace:
+[  150.714975]  asymmetric_key_free_preparse+0x2f/0x40
+[  150.715907]  key_update+0xf7/0x140
+[  150.716560]  ? key_default_cmp+0x20/0x20
+[  150.717319]  keyctl_update_key+0xb0/0xe0
+[  150.718066]  SyS_keyctl+0x109/0x130
+[  150.718663]  entry_SYSCALL_64_fastpath+0x1f/0xc2
+[  150.719440] RIP: 0033:0x7fcbce75ff19
+[  150.719926] RSP: 002b:00007ffd5d167088 EFLAGS: 00000206 ORIG_RAX: 00000000000000fa
+[  150.720918] RAX: ffffffffffffffda RBX: 0000000000404d80 RCX: 00007fcbce75ff19
+[  150.721874] RDX: 00007ffd5d16785e RSI: 000000002866cd36 RDI: 0000000000000002
+[  150.722827] RBP: 0000000000000006 R08: 000000002866cd36 R09: 00007ffd5d16785e
+[  150.723781] R10: 0000000000000004 R11: 0000000000000206 R12: 0000000000404d80
+[  150.724650] R13: 00007ffd5d16784d R14: 00007ffd5d167238 R15: 000000000040411f
+[  150.725447] Code: 83 c4 08 31 c0 5b 41 5c 41 5d 41 5e 41 5f 5d c3 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 85 ff 74 23 55 48 89 e5 53 48 89 fb <48> 8b 3f e8 06 21 c5 ff 48 8b 7b 08 e8 fd 20 c5 ff 48 89 df e8
+[  150.727489] RIP: asymmetric_key_free_kids+0x12/0x30 RSP: ffffc90000353e58
+[  150.728117] CR2: 0000000000000001
+[  150.728430] ---[ end trace f7f8fe1da2d5ae8d ]---
+
+Fixes: 4d8c0250b841 ("KEYS: Call ->free_preparse() even after ->preparse() returns an error")
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: James Morris <james.l.morris@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/keys/key.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/security/keys/key.c
++++ b/security/keys/key.c
+@@ -936,12 +936,11 @@ int key_update(key_ref_t key_ref, const
+       /* the key must be writable */
+       ret = key_permission(key_ref, KEY_NEED_WRITE);
+       if (ret < 0)
+-              goto error;
++              return ret;
+       /* attempt to update it if supported */
+-      ret = -EOPNOTSUPP;
+       if (!key->type->update)
+-              goto error;
++              return -EOPNOTSUPP;
+       memset(&prep, 0, sizeof(prep));
+       prep.data = payload;
diff --git a/queue-3.18/nfsd4-fix-null-dereference-on-replay.patch b/queue-3.18/nfsd4-fix-null-dereference-on-replay.patch
new file mode 100644 (file)
index 0000000..539be06
--- /dev/null
@@ -0,0 +1,82 @@
+From 9a307403d374b993061f5992a6e260c944920d0b Mon Sep 17 00:00:00 2001
+From: "J. Bruce Fields" <bfields@redhat.com>
+Date: Tue, 23 May 2017 12:24:40 -0400
+Subject: nfsd4: fix null dereference on replay
+
+From: J. Bruce Fields <bfields@redhat.com>
+
+commit 9a307403d374b993061f5992a6e260c944920d0b upstream.
+
+if we receive a compound such that:
+
+       - the sessionid, slot, and sequence number in the SEQUENCE op
+         match a cached succesful reply with N ops, and
+       - the Nth operation of the compound is a PUTFH, PUTPUBFH,
+         PUTROOTFH, or RESTOREFH,
+
+then nfsd4_sequence will return 0 and set cstate->status to
+nfserr_replay_cache.  The current filehandle will not be set.  This will
+cause us to call check_nfsd_access with first argument NULL.
+
+To nfsd4_compound it looks like we just succesfully executed an
+operation that set a filehandle, but the current filehandle is not set.
+
+Fix this by moving the nfserr_replay_cache earlier.  There was never any
+reason to have it after the encode_op label, since the only case where
+he hit that is when opdesc->op_func sets it.
+
+Note that there are two ways we could hit this case:
+
+       - a client is resending a previously sent compound that ended
+         with one of the four PUTFH-like operations, or
+       - a client is sending a *new* compound that (incorrectly) shares
+         sessionid, slot, and sequence number with a previously sent
+         compound, and the length of the previously sent compound
+         happens to match the position of a PUTFH-like operation in the
+         new compound.
+
+The second is obviously incorrect client behavior.  The first is also
+very strange--the only purpose of a PUTFH-like operation is to set the
+current filehandle to be used by the following operation, so there's no
+point in having it as the last in a compound.
+
+So it's likely this requires a buggy or malicious client to reproduce.
+
+Reported-by: Scott Mayhew <smayhew@redhat.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfsd/nfs4proc.c |   13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+--- a/fs/nfsd/nfs4proc.c
++++ b/fs/nfsd/nfs4proc.c
+@@ -1405,6 +1405,12 @@ nfsd4_proc_compound(struct svc_rqst *rqs
+                       opdesc->op_get_currentstateid(cstate, &op->u);
+               op->status = opdesc->op_func(rqstp, cstate, &op->u);
++              /* Only from SEQUENCE */
++              if (cstate->status == nfserr_replay_cache) {
++                      dprintk("%s NFS4.1 replay from cache\n", __func__);
++                      status = op->status;
++                      goto out;
++              }
+               if (!op->status) {
+                       if (opdesc->op_set_currentstateid)
+                               opdesc->op_set_currentstateid(cstate, &op->u);
+@@ -1415,14 +1421,7 @@ nfsd4_proc_compound(struct svc_rqst *rqs
+                       if (need_wrongsec_check(rqstp))
+                               op->status = check_nfsd_access(current_fh->fh_export, rqstp);
+               }
+-
+ encode_op:
+-              /* Only from SEQUENCE */
+-              if (cstate->status == nfserr_replay_cache) {
+-                      dprintk("%s NFS4.1 replay from cache\n", __func__);
+-                      status = op->status;
+-                      goto out;
+-              }
+               if (op->status == nfserr_replay_me) {
+                       op->replay = &cstate->replay_owner->so_replay;
+                       nfsd4_encode_replay(&resp->xdr, op);
index eb862ca902977ab5acc89e6b232d977b242a606b..24305b23d141c19b6f4cb791bec13b56b7057547 100644 (file)
@@ -6,3 +6,7 @@ ipv6-fix-leak-in-ipv6_gso_segment.patch
 net-ping-do-not-abuse-udp_poll.patch
 net-ethoc-enable-napi-before-poll-may-be-scheduled.patch
 serial-ifx6x60-fix-use-after-free-on-module-unload.patch
+keys-fix-dereferencing-null-payload-with-nonzero-length.patch
+keys-fix-freeing-uninitialized-memory-in-key_update.patch
+crypto-gcm-wait-for-crypto-op-not-signal-safe.patch
+nfsd4-fix-null-dereference-on-replay.patch