From: Greg Kroah-Hartman Date: Mon, 12 Jun 2017 07:42:58 +0000 (+0200) Subject: 3.18-stable patches X-Git-Tag: v3.18.57~32 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7b34a0d9bb45c6ee4d2894ac53689681ae1a34f5;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches 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 --- 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 index 00000000000..adb3cfa25f0 --- /dev/null +++ b/queue-3.18/crypto-gcm-wait-for-crypto-op-not-signal-safe.patch @@ -0,0 +1,40 @@ +From f3ad587070d6bd961ab942b3fd7a85d00dfc934b Mon Sep 17 00:00:00 2001 +From: Gilad Ben-Yossef +Date: Thu, 18 May 2017 16:29:25 +0300 +Subject: crypto: gcm - wait for crypto op not signal safe + +From: Gilad Ben-Yossef + +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 +Signed-off-by: Gilad Ben-Yossef +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..045118573dd --- /dev/null +++ b/queue-3.18/keys-fix-dereferencing-null-payload-with-nonzero-length.patch @@ -0,0 +1,48 @@ +From 5649645d725c73df4302428ee4e02c869248b4c5 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Thu, 8 Jun 2017 14:48:40 +0100 +Subject: KEYS: fix dereferencing NULL payload with nonzero length + +From: Eric Biggers + +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 +Signed-off-by: David Howells +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..0d28385d998 --- /dev/null +++ b/queue-3.18/keys-fix-freeing-uninitialized-memory-in-key_update.patch @@ -0,0 +1,91 @@ +From 63a0b0509e700717a59f049ec6e4e04e903c7fe2 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Thu, 8 Jun 2017 14:48:47 +0100 +Subject: KEYS: fix freeing uninitialized memory in key_update() + +From: Eric Biggers + +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 +Signed-off-by: David Howells +Signed-off-by: James Morris +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..539be0631a3 --- /dev/null +++ b/queue-3.18/nfsd4-fix-null-dereference-on-replay.patch @@ -0,0 +1,82 @@ +From 9a307403d374b993061f5992a6e260c944920d0b Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Tue, 23 May 2017 12:24:40 -0400 +Subject: nfsd4: fix null dereference on replay + +From: J. Bruce Fields + +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 +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-3.18/series b/queue-3.18/series index eb862ca9029..24305b23d14 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -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