]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Nov 2013 21:16:23 +0000 (13:16 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Nov 2013 21:16:23 +0000 (13:16 -0800)
added patches:
can-c_can-fix-rx-message-handling-handle-lost-message-before-eob.patch
crypto-ansi_cprng-fix-off-by-one-error-in-non-block-size-request.patch
crypto-s390-fix-aes-cbc-iv-corruption.patch
drm-nv50-disp-remove-dcb_outp_match-call-and-related-variables.patch
drm-nva3-disp-fix-hda-eld-writing-needs-to-be-padded.patch
ipc-shm-correct-error-return-value-in-shmctl-shm_unlock.patch
ipc-shm-fix-shm_file-deletion-races.patch

queue-3.10/can-c_can-fix-rx-message-handling-handle-lost-message-before-eob.patch [new file with mode: 0644]
queue-3.10/crypto-ansi_cprng-fix-off-by-one-error-in-non-block-size-request.patch [new file with mode: 0644]
queue-3.10/crypto-s390-fix-aes-cbc-iv-corruption.patch [new file with mode: 0644]
queue-3.10/drm-nv50-disp-remove-dcb_outp_match-call-and-related-variables.patch [new file with mode: 0644]
queue-3.10/drm-nva3-disp-fix-hda-eld-writing-needs-to-be-padded.patch [new file with mode: 0644]
queue-3.10/ipc-shm-correct-error-return-value-in-shmctl-shm_unlock.patch [new file with mode: 0644]
queue-3.10/ipc-shm-fix-shm_file-deletion-races.patch [new file with mode: 0644]
queue-3.10/series

diff --git a/queue-3.10/can-c_can-fix-rx-message-handling-handle-lost-message-before-eob.patch b/queue-3.10/can-c_can-fix-rx-message-handling-handle-lost-message-before-eob.patch
new file mode 100644 (file)
index 0000000..a117e03
--- /dev/null
@@ -0,0 +1,47 @@
+From 5d0f801a2ccec3b1fdabc3392c8d99ed0413d216 Mon Sep 17 00:00:00 2001
+From: Markus Pargmann <mpa@pengutronix.de>
+Date: Mon, 28 Oct 2013 09:54:40 +0100
+Subject: can: c_can: Fix RX message handling, handle lost message before EOB
+
+From: Markus Pargmann <mpa@pengutronix.de>
+
+commit 5d0f801a2ccec3b1fdabc3392c8d99ed0413d216 upstream.
+
+If we handle end of block messages with higher priority than a lost message,
+we can run into an endless interrupt loop.
+
+This is reproducable with a am335x processor and "cansequence -r" at 1Mbit.
+As soon as we loose a packet we can't escape from an interrupt loop.
+
+This patch fixes the problem by handling lost packets before EOB packets.
+
+Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/can/c_can/c_can.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/can/c_can/c_can.c
++++ b/drivers/net/can/c_can/c_can.c
+@@ -814,9 +814,6 @@ static int c_can_do_rx_poll(struct net_d
+                       msg_ctrl_save = priv->read_reg(priv,
+                                       C_CAN_IFACE(MSGCTRL_REG, 0));
+-                      if (msg_ctrl_save & IF_MCONT_EOB)
+-                              return num_rx_pkts;
+-
+                       if (msg_ctrl_save & IF_MCONT_MSGLST) {
+                               c_can_handle_lost_msg_obj(dev, 0, msg_obj);
+                               num_rx_pkts++;
+@@ -824,6 +821,9 @@ static int c_can_do_rx_poll(struct net_d
+                               continue;
+                       }
++                      if (msg_ctrl_save & IF_MCONT_EOB)
++                              return num_rx_pkts;
++
+                       if (!(msg_ctrl_save & IF_MCONT_NEWDAT))
+                               continue;
diff --git a/queue-3.10/crypto-ansi_cprng-fix-off-by-one-error-in-non-block-size-request.patch b/queue-3.10/crypto-ansi_cprng-fix-off-by-one-error-in-non-block-size-request.patch
new file mode 100644 (file)
index 0000000..9f0fa2f
--- /dev/null
@@ -0,0 +1,49 @@
+From 714b33d15130cbb5ab426456d4e3de842d6c5b8a Mon Sep 17 00:00:00 2001
+From: Neil Horman <nhorman@tuxdriver.com>
+Date: Tue, 17 Sep 2013 08:33:11 -0400
+Subject: crypto: ansi_cprng - Fix off by one error in non-block size request
+
+From: Neil Horman <nhorman@tuxdriver.com>
+
+commit 714b33d15130cbb5ab426456d4e3de842d6c5b8a upstream.
+
+Stephan Mueller reported to me recently a error in random number generation in
+the ansi cprng. If several small requests are made that are less than the
+instances block size, the remainder for loop code doesn't increment
+rand_data_valid in the last iteration, meaning that the last bytes in the
+rand_data buffer gets reused on the subsequent smaller-than-a-block request for
+random data.
+
+The fix is pretty easy, just re-code the for loop to make sure that
+rand_data_valid gets incremented appropriately
+
+Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
+Reported-by: Stephan Mueller <stephan.mueller@atsec.com>
+CC: Stephan Mueller <stephan.mueller@atsec.com>
+CC: Petr Matousek <pmatouse@redhat.com>
+CC: Herbert Xu <herbert@gondor.apana.org.au>
+CC: "David S. Miller" <davem@davemloft.net>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: Luis Henriques <luis.henriques@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/ansi_cprng.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/crypto/ansi_cprng.c
++++ b/crypto/ansi_cprng.c
+@@ -230,11 +230,11 @@ remainder:
+        */
+       if (byte_count < DEFAULT_BLK_SZ) {
+ empty_rbuf:
+-              for (; ctx->rand_data_valid < DEFAULT_BLK_SZ;
+-                      ctx->rand_data_valid++) {
++              while (ctx->rand_data_valid < DEFAULT_BLK_SZ) {
+                       *ptr = ctx->rand_data[ctx->rand_data_valid];
+                       ptr++;
+                       byte_count--;
++                      ctx->rand_data_valid++;
+                       if (byte_count == 0)
+                               goto done;
+               }
diff --git a/queue-3.10/crypto-s390-fix-aes-cbc-iv-corruption.patch b/queue-3.10/crypto-s390-fix-aes-cbc-iv-corruption.patch
new file mode 100644 (file)
index 0000000..1c41a5b
--- /dev/null
@@ -0,0 +1,95 @@
+From f262f0f5cad0c9eca61d1d383e3b67b57dcbe5ea Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Tue, 5 Nov 2013 19:36:27 +0800
+Subject: crypto: s390 - Fix aes-cbc IV corruption
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+commit f262f0f5cad0c9eca61d1d383e3b67b57dcbe5ea upstream.
+
+The cbc-aes-s390 algorithm incorrectly places the IV in the tfm
+data structure.  As the tfm is shared between multiple threads,
+this introduces a possibility of data corruption.
+
+This patch fixes this by moving the parameter block containing
+the IV and key onto the stack (the block is 48 bytes long).
+
+The same bug exists elsewhere in the s390 crypto system and they
+will be fixed in subsequent patches.
+
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/s390/crypto/aes_s390.c |   19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+--- a/arch/s390/crypto/aes_s390.c
++++ b/arch/s390/crypto/aes_s390.c
+@@ -35,7 +35,6 @@ static u8 *ctrblk;
+ static char keylen_flag;
+ struct s390_aes_ctx {
+-      u8 iv[AES_BLOCK_SIZE];
+       u8 key[AES_MAX_KEY_SIZE];
+       long enc;
+       long dec;
+@@ -441,30 +440,36 @@ static int cbc_aes_set_key(struct crypto
+       return aes_set_key(tfm, in_key, key_len);
+ }
+-static int cbc_aes_crypt(struct blkcipher_desc *desc, long func, void *param,
++static int cbc_aes_crypt(struct blkcipher_desc *desc, long func,
+                        struct blkcipher_walk *walk)
+ {
++      struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+       int ret = blkcipher_walk_virt(desc, walk);
+       unsigned int nbytes = walk->nbytes;
++      struct {
++              u8 iv[AES_BLOCK_SIZE];
++              u8 key[AES_MAX_KEY_SIZE];
++      } param;
+       if (!nbytes)
+               goto out;
+-      memcpy(param, walk->iv, AES_BLOCK_SIZE);
++      memcpy(param.iv, walk->iv, AES_BLOCK_SIZE);
++      memcpy(param.key, sctx->key, sctx->key_len);
+       do {
+               /* only use complete blocks */
+               unsigned int n = nbytes & ~(AES_BLOCK_SIZE - 1);
+               u8 *out = walk->dst.virt.addr;
+               u8 *in = walk->src.virt.addr;
+-              ret = crypt_s390_kmc(func, param, out, in, n);
++              ret = crypt_s390_kmc(func, &param, out, in, n);
+               if (ret < 0 || ret != n)
+                       return -EIO;
+               nbytes &= AES_BLOCK_SIZE - 1;
+               ret = blkcipher_walk_done(desc, walk, nbytes);
+       } while ((nbytes = walk->nbytes));
+-      memcpy(walk->iv, param, AES_BLOCK_SIZE);
++      memcpy(walk->iv, param.iv, AES_BLOCK_SIZE);
+ out:
+       return ret;
+@@ -481,7 +486,7 @@ static int cbc_aes_encrypt(struct blkcip
+               return fallback_blk_enc(desc, dst, src, nbytes);
+       blkcipher_walk_init(&walk, dst, src, nbytes);
+-      return cbc_aes_crypt(desc, sctx->enc, sctx->iv, &walk);
++      return cbc_aes_crypt(desc, sctx->enc, &walk);
+ }
+ static int cbc_aes_decrypt(struct blkcipher_desc *desc,
+@@ -495,7 +500,7 @@ static int cbc_aes_decrypt(struct blkcip
+               return fallback_blk_dec(desc, dst, src, nbytes);
+       blkcipher_walk_init(&walk, dst, src, nbytes);
+-      return cbc_aes_crypt(desc, sctx->dec, sctx->iv, &walk);
++      return cbc_aes_crypt(desc, sctx->dec, &walk);
+ }
+ static struct crypto_alg cbc_aes_alg = {
diff --git a/queue-3.10/drm-nv50-disp-remove-dcb_outp_match-call-and-related-variables.patch b/queue-3.10/drm-nv50-disp-remove-dcb_outp_match-call-and-related-variables.patch
new file mode 100644 (file)
index 0000000..bd0bba6
--- /dev/null
@@ -0,0 +1,46 @@
+From 9a7046d55f319b2dde5d2536cc2adb01ebdbe09e Mon Sep 17 00:00:00 2001
+From: Emil Velikov <emil.l.velikov@gmail.com>
+Date: Sun, 28 Jul 2013 21:00:23 +0100
+Subject: drm/nv50-/disp: remove dcb_outp_match call, and related variables
+
+From: Emil Velikov <emil.l.velikov@gmail.com>
+
+commit 9a7046d55f319b2dde5d2536cc2adb01ebdbe09e upstream.
+
+Unused and irrelavant since the code move of DP training/linkcontrol interrupt
+
+Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Cc: Ilia Mirkin <imirkin@alum.mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c |    8 --------
+ 1 file changed, 8 deletions(-)
+
+--- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c
++++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c
+@@ -47,14 +47,8 @@ int
+ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size)
+ {
+       struct nv50_disp_priv *priv = (void *)object->engine;
+-      struct nouveau_bios *bios = nouveau_bios(priv);
+-      const u16 type = (mthd & NV50_DISP_SOR_MTHD_TYPE) >> 12;
+       const u8  head = (mthd & NV50_DISP_SOR_MTHD_HEAD) >> 3;
+-      const u8  link = (mthd & NV50_DISP_SOR_MTHD_LINK) >> 2;
+       const u8    or = (mthd & NV50_DISP_SOR_MTHD_OR);
+-      const u16 mask = (0x0100 << head) | (0x0040 << link) | (0x0001 << or);
+-      struct dcb_output outp;
+-      u8  ver, hdr;
+       u32 data;
+       int ret = -EINVAL;
+@@ -62,8 +56,6 @@ nv50_sor_mthd(struct nouveau_object *obj
+               return -EINVAL;
+       data = *(u32 *)args;
+-      if (type && !dcb_outp_match(bios, type, mask, &ver, &hdr, &outp))
+-              return -ENODEV;
+       switch (mthd & ~0x3f) {
+       case NV50_DISP_SOR_PWR:
diff --git a/queue-3.10/drm-nva3-disp-fix-hda-eld-writing-needs-to-be-padded.patch b/queue-3.10/drm-nva3-disp-fix-hda-eld-writing-needs-to-be-padded.patch
new file mode 100644 (file)
index 0000000..849c508
--- /dev/null
@@ -0,0 +1,50 @@
+From 02d69294a174d7cb6a76080b6d16971ca08728d4 Mon Sep 17 00:00:00 2001
+From: Ilia Mirkin <imirkin@alum.mit.edu>
+Date: Sun, 28 Jul 2013 22:30:57 -0400
+Subject: drm/nva3-/disp: fix hda eld writing, needs to be padded
+
+From: Ilia Mirkin <imirkin@alum.mit.edu>
+
+commit 02d69294a174d7cb6a76080b6d16971ca08728d4 upstream.
+
+Commits 0a9e2b959 (drm/nvd0/disp: move HDA codec setup to core) and
+a4feaf4ea (drm/nva3/disp: move hda codec handling to core) moved code
+around but neglected to fill data up to 0x60 as before. This caused
+/proc/asound/cardN/eld#3.0 to show eld_valid as 0. With this patch, that
+file is again populated with the correct data.
+
+See https://bugs.freedesktop.org/show_bug.cgi?id=67051
+
+Reported-and-tested-by: Alex <alupu01@gmail.com>
+Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
+Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
+Cc: Ilia Mirkin <imirkin@alum.mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c |    2 ++
+ drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c |    2 ++
+ 2 files changed, 4 insertions(+)
+
+--- a/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c
++++ b/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c
+@@ -36,6 +36,8 @@ nva3_hda_eld(struct nv50_disp_priv *priv
+       if (data && data[0]) {
+               for (i = 0; i < size; i++)
+                       nv_wr32(priv, 0x61c440 + soff, (i << 8) | data[i]);
++              for (; i < 0x60; i++)
++                      nv_wr32(priv, 0x61c440 + soff, (i << 8));
+               nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000003);
+       } else
+       if (data) {
+--- a/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c
++++ b/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c
+@@ -41,6 +41,8 @@ nvd0_hda_eld(struct nv50_disp_priv *priv
+       if (data && data[0]) {
+               for (i = 0; i < size; i++)
+                       nv_wr32(priv, 0x10ec00 + soff, (i << 8) | data[i]);
++              for (; i < 0x60; i++)
++                      nv_wr32(priv, 0x10ec00 + soff, (i << 8));
+               nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000003);
+       } else
+       if (data) {
diff --git a/queue-3.10/ipc-shm-correct-error-return-value-in-shmctl-shm_unlock.patch b/queue-3.10/ipc-shm-correct-error-return-value-in-shmctl-shm_unlock.patch
new file mode 100644 (file)
index 0000000..c25cd67
--- /dev/null
@@ -0,0 +1,58 @@
+From 3a72660b07d86d60457ca32080b1ce8c2b628ee2 Mon Sep 17 00:00:00 2001
+From: Jesper Nilsson <jesper.nilsson@axis.com>
+Date: Thu, 21 Nov 2013 14:32:08 -0800
+Subject: ipc,shm: correct error return value in shmctl (SHM_UNLOCK)
+
+From: Jesper Nilsson <jesper.nilsson@axis.com>
+
+commit 3a72660b07d86d60457ca32080b1ce8c2b628ee2 upstream.
+
+Commit 2caacaa82a51 ("ipc,shm: shorten critical region for shmctl")
+restructured the ipc shm to shorten critical region, but introduced a
+path where the return value could be -EPERM, even if the operation
+actually was performed.
+
+Before the commit, the err return value was reset by the return value
+from security_shm_shmctl() after the if (!ns_capable(...)) statement.
+
+Now, we still exit the if statement with err set to -EPERM, and in the
+case of SHM_UNLOCK, it is not reset at all, and used as the return value
+from shmctl.
+
+To fix this, we only set err when errors occur, leaving the fallthrough
+case alone.
+
+Signed-off-by: Jesper Nilsson <jesper.nilsson@axis.com>
+Cc: Davidlohr Bueso <davidlohr@hp.com>
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Michel Lespinasse <walken@google.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ ipc/shm.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/ipc/shm.c
++++ b/ipc/shm.c
+@@ -974,12 +974,15 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int,
+               ipc_lock_object(&shp->shm_perm);
+               if (!ns_capable(ns->user_ns, CAP_IPC_LOCK)) {
+                       kuid_t euid = current_euid();
+-                      err = -EPERM;
+                       if (!uid_eq(euid, shp->shm_perm.uid) &&
+-                          !uid_eq(euid, shp->shm_perm.cuid))
++                          !uid_eq(euid, shp->shm_perm.cuid)) {
++                              err = -EPERM;
+                               goto out_unlock0;
+-                      if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK))
++                      }
++                      if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK)) {
++                              err = -EPERM;
+                               goto out_unlock0;
++                      }
+               }
+               shm_file = shp->shm_file;
diff --git a/queue-3.10/ipc-shm-fix-shm_file-deletion-races.patch b/queue-3.10/ipc-shm-fix-shm_file-deletion-races.patch
new file mode 100644 (file)
index 0000000..1e687cf
--- /dev/null
@@ -0,0 +1,158 @@
+From a399b29dfbaaaf91162b2dc5a5875dd51bbfa2a1 Mon Sep 17 00:00:00 2001
+From: Greg Thelen <gthelen@google.com>
+Date: Thu, 21 Nov 2013 14:32:00 -0800
+Subject: ipc,shm: fix shm_file deletion races
+
+From: Greg Thelen <gthelen@google.com>
+
+commit a399b29dfbaaaf91162b2dc5a5875dd51bbfa2a1 upstream.
+
+When IPC_RMID races with other shm operations there's potential for
+use-after-free of the shm object's associated file (shm_file).
+
+Here's the race before this patch:
+
+  TASK 1                     TASK 2
+  ------                     ------
+  shm_rmid()
+    ipc_lock_object()
+                             shmctl()
+                             shp = shm_obtain_object_check()
+
+    shm_destroy()
+      shum_unlock()
+      fput(shp->shm_file)
+                             ipc_lock_object()
+                             shmem_lock(shp->shm_file)
+                             <OOPS>
+
+The oops is caused because shm_destroy() calls fput() after dropping the
+ipc_lock.  fput() clears the file's f_inode, f_path.dentry, and
+f_path.mnt, which causes various NULL pointer references in task 2.  I
+reliably see the oops in task 2 if with shmlock, shmu
+
+This patch fixes the races by:
+1) set shm_file=NULL in shm_destroy() while holding ipc_object_lock().
+2) modify at risk operations to check shm_file while holding
+   ipc_object_lock().
+
+Example workloads, which each trigger oops...
+
+Workload 1:
+  while true; do
+    id=$(shmget 1 4096)
+    shm_rmid $id &
+    shmlock $id &
+    wait
+  done
+
+  The oops stack shows accessing NULL f_inode due to racing fput:
+    _raw_spin_lock
+    shmem_lock
+    SyS_shmctl
+
+Workload 2:
+  while true; do
+    id=$(shmget 1 4096)
+    shmat $id 4096 &
+    shm_rmid $id &
+    wait
+  done
+
+  The oops stack is similar to workload 1 due to NULL f_inode:
+    touch_atime
+    shmem_mmap
+    shm_mmap
+    mmap_region
+    do_mmap_pgoff
+    do_shmat
+    SyS_shmat
+
+Workload 3:
+  while true; do
+    id=$(shmget 1 4096)
+    shmlock $id
+    shm_rmid $id &
+    shmunlock $id &
+    wait
+  done
+
+  The oops stack shows second fput tripping on an NULL f_inode.  The
+  first fput() completed via from shm_destroy(), but a racing thread did
+  a get_file() and queued this fput():
+    locks_remove_flock
+    __fput
+    ____fput
+    task_work_run
+    do_notify_resume
+    int_signal
+
+Fixes: c2c737a0461e ("ipc,shm: shorten critical region for shmat")
+Fixes: 2caacaa82a51 ("ipc,shm: shorten critical region for shmctl")
+Signed-off-by: Greg Thelen <gthelen@google.com>
+Cc: Davidlohr Bueso <davidlohr@hp.com>
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Manfred Spraul <manfred@colorfullife.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ ipc/shm.c |   28 +++++++++++++++++++++++-----
+ 1 file changed, 23 insertions(+), 5 deletions(-)
+
+--- a/ipc/shm.c
++++ b/ipc/shm.c
+@@ -208,15 +208,18 @@ static void shm_open(struct vm_area_stru
+  */
+ static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
+ {
++      struct file *shm_file;
++
++      shm_file = shp->shm_file;
++      shp->shm_file = NULL;
+       ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
+       shm_rmid(ns, shp);
+       shm_unlock(shp);
+-      if (!is_file_hugepages(shp->shm_file))
+-              shmem_lock(shp->shm_file, 0, shp->mlock_user);
++      if (!is_file_hugepages(shm_file))
++              shmem_lock(shm_file, 0, shp->mlock_user);
+       else if (shp->mlock_user)
+-              user_shm_unlock(file_inode(shp->shm_file)->i_size,
+-                                              shp->mlock_user);
+-      fput (shp->shm_file);
++              user_shm_unlock(file_inode(shm_file)->i_size, shp->mlock_user);
++      fput(shm_file);
+       ipc_rcu_putref(shp, shm_rcu_free);
+ }
+@@ -986,6 +989,13 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int,
+               }
+               shm_file = shp->shm_file;
++
++              /* check if shm_destroy() is tearing down shp */
++              if (shm_file == NULL) {
++                      err = -EIDRM;
++                      goto out_unlock0;
++              }
++
+               if (is_file_hugepages(shm_file))
+                       goto out_unlock0;
+@@ -1104,6 +1114,14 @@ long do_shmat(int shmid, char __user *sh
+               goto out_unlock;
+       ipc_lock_object(&shp->shm_perm);
++
++      /* check if shm_destroy() is tearing down shp */
++      if (shp->shm_file == NULL) {
++              ipc_unlock_object(&shp->shm_perm);
++              err = -EIDRM;
++              goto out_unlock;
++      }
++
+       path = shp->shm_file->f_path;
+       path_get(&path);
+       shp->shm_nattch++;
index 86c55e541bbd8d6e6367055842148c9d41b59dfd..1f8644eb779641fd5177ca309ddc332b8e28ec36 100644 (file)
@@ -5,3 +5,10 @@ acpica-return-error-if-derefof-resolves-to-a-null-package-element.patch
 acpica-fix-for-a-store-argx-when-argx-contains-a-reference-to-a-field.patch
 usb-mos7840-fix-tiocmget-error-handling.patch
 can-kvaser_usb-fix-usb-endpoints-detection.patch
+crypto-ansi_cprng-fix-off-by-one-error-in-non-block-size-request.patch
+crypto-s390-fix-aes-cbc-iv-corruption.patch
+can-c_can-fix-rx-message-handling-handle-lost-message-before-eob.patch
+ipc-shm-correct-error-return-value-in-shmctl-shm_unlock.patch
+ipc-shm-fix-shm_file-deletion-races.patch
+drm-nv50-disp-remove-dcb_outp_match-call-and-related-variables.patch
+drm-nva3-disp-fix-hda-eld-writing-needs-to-be-padded.patch