From: Greg Kroah-Hartman Date: Mon, 25 Nov 2013 21:16:23 +0000 (-0800) Subject: 3.10-stable patches X-Git-Tag: v3.11.10~44 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6f75671f2acfbf2e1bfb980eaa9fa0004fd1567c;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches 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 --- 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 index 00000000000..a117e0380ef --- /dev/null +++ b/queue-3.10/can-c_can-fix-rx-message-handling-handle-lost-message-before-eob.patch @@ -0,0 +1,47 @@ +From 5d0f801a2ccec3b1fdabc3392c8d99ed0413d216 Mon Sep 17 00:00:00 2001 +From: Markus Pargmann +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 + +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 +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..9f0fa2f9f62 --- /dev/null +++ b/queue-3.10/crypto-ansi_cprng-fix-off-by-one-error-in-non-block-size-request.patch @@ -0,0 +1,49 @@ +From 714b33d15130cbb5ab426456d4e3de842d6c5b8a Mon Sep 17 00:00:00 2001 +From: Neil Horman +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 + +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 +Reported-by: Stephan Mueller +CC: Stephan Mueller +CC: Petr Matousek +CC: Herbert Xu +CC: "David S. Miller" +Signed-off-by: Herbert Xu +Cc: Luis Henriques +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..1c41a5b903b --- /dev/null +++ b/queue-3.10/crypto-s390-fix-aes-cbc-iv-corruption.patch @@ -0,0 +1,95 @@ +From f262f0f5cad0c9eca61d1d383e3b67b57dcbe5ea Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Tue, 5 Nov 2013 19:36:27 +0800 +Subject: crypto: s390 - Fix aes-cbc IV corruption + +From: Herbert Xu + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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, ¶m, 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 index 00000000000..bd0bba63fcb --- /dev/null +++ b/queue-3.10/drm-nv50-disp-remove-dcb_outp_match-call-and-related-variables.patch @@ -0,0 +1,46 @@ +From 9a7046d55f319b2dde5d2536cc2adb01ebdbe09e Mon Sep 17 00:00:00 2001 +From: Emil Velikov +Date: Sun, 28 Jul 2013 21:00:23 +0100 +Subject: drm/nv50-/disp: remove dcb_outp_match call, and related variables + +From: Emil Velikov + +commit 9a7046d55f319b2dde5d2536cc2adb01ebdbe09e upstream. + +Unused and irrelavant since the code move of DP training/linkcontrol interrupt + +Signed-off-by: Emil Velikov +Signed-off-by: Ben Skeggs +Cc: Ilia Mirkin +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..849c5080059 --- /dev/null +++ b/queue-3.10/drm-nva3-disp-fix-hda-eld-writing-needs-to-be-padded.patch @@ -0,0 +1,50 @@ +From 02d69294a174d7cb6a76080b6d16971ca08728d4 Mon Sep 17 00:00:00 2001 +From: Ilia Mirkin +Date: Sun, 28 Jul 2013 22:30:57 -0400 +Subject: drm/nva3-/disp: fix hda eld writing, needs to be padded + +From: Ilia Mirkin + +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 +Signed-off-by: Ilia Mirkin +Signed-off-by: Ben Skeggs +Cc: Ilia Mirkin +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..c25cd670341 --- /dev/null +++ b/queue-3.10/ipc-shm-correct-error-return-value-in-shmctl-shm_unlock.patch @@ -0,0 +1,58 @@ +From 3a72660b07d86d60457ca32080b1ce8c2b628ee2 Mon Sep 17 00:00:00 2001 +From: Jesper Nilsson +Date: Thu, 21 Nov 2013 14:32:08 -0800 +Subject: ipc,shm: correct error return value in shmctl (SHM_UNLOCK) + +From: Jesper Nilsson + +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 +Cc: Davidlohr Bueso +Cc: Rik van Riel +Cc: Michel Lespinasse +Cc: Al Viro +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..1e687cf141f --- /dev/null +++ b/queue-3.10/ipc-shm-fix-shm_file-deletion-races.patch @@ -0,0 +1,158 @@ +From a399b29dfbaaaf91162b2dc5a5875dd51bbfa2a1 Mon Sep 17 00:00:00 2001 +From: Greg Thelen +Date: Thu, 21 Nov 2013 14:32:00 -0800 +Subject: ipc,shm: fix shm_file deletion races + +From: Greg Thelen + +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) + + +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 +Cc: Davidlohr Bueso +Cc: Rik van Riel +Cc: Manfred Spraul +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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++; diff --git a/queue-3.10/series b/queue-3.10/series index 86c55e541bb..1f8644eb779 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -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