From: Greg Kroah-Hartman Date: Sat, 8 Nov 2014 01:29:27 +0000 (-0800) Subject: 3.14-stable patches X-Git-Tag: v3.10.60~68 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1e714e696b1911106e484b85756f2723cfa12c48;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches added patches: alsa-pcm-zero-clear-reserved-fields-of-pcm-status-ioctl-in-compat-mode.patch evm-check-xattr-value-length-and-type-in-evm_inode_setxattr.patch evm-properly-handle-integrity_noxattrs-evm-status.patch fix-misuses-of-f_count-in-ppp-and-netlink.patch kill-wbuf_queued-wbuf_dwork_lock.patch libceph-ceph-msgr-workqueue-needs-a-resque-worker.patch missing-data-dependency-barrier-in-prepend_name.patch sched-use-dl_bw_of-under-rcu-read-lock.patch um-ubd-fix-for-processes-stuck-in-d-state-forever.patch --- diff --git a/queue-3.14/alsa-pcm-zero-clear-reserved-fields-of-pcm-status-ioctl-in-compat-mode.patch b/queue-3.14/alsa-pcm-zero-clear-reserved-fields-of-pcm-status-ioctl-in-compat-mode.patch new file mode 100644 index 00000000000..63f99c48a16 --- /dev/null +++ b/queue-3.14/alsa-pcm-zero-clear-reserved-fields-of-pcm-status-ioctl-in-compat-mode.patch @@ -0,0 +1,33 @@ +From 317168d0c766defd14b3d0e9c2c4a9a258b803ee Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 28 Oct 2014 12:42:19 +0100 +Subject: ALSA: pcm: Zero-clear reserved fields of PCM status ioctl in compat mode + +From: Takashi Iwai + +commit 317168d0c766defd14b3d0e9c2c4a9a258b803ee upstream. + +In compat mode, we copy each field of snd_pcm_status struct but don't +touch the reserved fields, and this leaves uninitialized values +there. Meanwhile the native ioctl does zero-clear the whole +structure, so we should follow the same rule in compat mode, too. + +Reported-by: Pierre-Louis Bossart +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/pcm_compat.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/sound/core/pcm_compat.c ++++ b/sound/core/pcm_compat.c +@@ -206,6 +206,8 @@ static int snd_pcm_status_user_compat(st + if (err < 0) + return err; + ++ if (clear_user(src, sizeof(*src))) ++ return -EFAULT; + if (put_user(status.state, &src->state) || + compat_put_timespec(&status.trigger_tstamp, &src->trigger_tstamp) || + compat_put_timespec(&status.tstamp, &src->tstamp) || diff --git a/queue-3.14/evm-check-xattr-value-length-and-type-in-evm_inode_setxattr.patch b/queue-3.14/evm-check-xattr-value-length-and-type-in-evm_inode_setxattr.patch new file mode 100644 index 00000000000..d9a822980b7 --- /dev/null +++ b/queue-3.14/evm-check-xattr-value-length-and-type-in-evm_inode_setxattr.patch @@ -0,0 +1,85 @@ +From 3b1deef6b1289a99505858a3b212c5b50adf0c2f Mon Sep 17 00:00:00 2001 +From: Dmitry Kasatkin +Date: Tue, 28 Oct 2014 14:28:49 +0200 +Subject: evm: check xattr value length and type in evm_inode_setxattr() + +From: Dmitry Kasatkin + +commit 3b1deef6b1289a99505858a3b212c5b50adf0c2f upstream. + +evm_inode_setxattr() can be called with no value. The function does not +check the length so that following command can be used to produce the +kernel oops: setfattr -n security.evm FOO. This patch fixes it. + +Changes in v3: +* there is no reason to return different error codes for EVM_XATTR_HMAC + and non EVM_XATTR_HMAC. Remove unnecessary test then. + +Changes in v2: +* testing for validity of xattr type + +[ 1106.396921] BUG: unable to handle kernel NULL pointer dereference at (null) +[ 1106.398192] IP: [] evm_inode_setxattr+0x2a/0x48 +[ 1106.399244] PGD 29048067 PUD 290d7067 PMD 0 +[ 1106.399953] Oops: 0000 [#1] SMP +[ 1106.400020] Modules linked in: bridge stp llc evdev serio_raw i2c_piix4 button fuse +[ 1106.400020] CPU: 0 PID: 3635 Comm: setxattr Not tainted 3.16.0-kds+ #2936 +[ 1106.400020] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 +[ 1106.400020] task: ffff8800291a0000 ti: ffff88002917c000 task.ti: ffff88002917c000 +[ 1106.400020] RIP: 0010:[] [] evm_inode_setxattr+0x2a/0x48 +[ 1106.400020] RSP: 0018:ffff88002917fd50 EFLAGS: 00010246 +[ 1106.400020] RAX: 0000000000000000 RBX: ffff88002917fdf8 RCX: 0000000000000000 +[ 1106.400020] RDX: 0000000000000000 RSI: ffffffff818136d3 RDI: ffff88002917fdf8 +[ 1106.400020] RBP: ffff88002917fd68 R08: 0000000000000000 R09: 00000000003ec1df +[ 1106.400020] R10: 0000000000000000 R11: 0000000000000000 R12: ffff8800438a0a00 +[ 1106.400020] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 +[ 1106.400020] FS: 00007f7dfa7d7740(0000) GS:ffff88005da00000(0000) knlGS:0000000000000000 +[ 1106.400020] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 1106.400020] CR2: 0000000000000000 CR3: 000000003763e000 CR4: 00000000000006f0 +[ 1106.400020] Stack: +[ 1106.400020] ffff8800438a0a00 ffff88002917fdf8 0000000000000000 ffff88002917fd98 +[ 1106.400020] ffffffff812a1030 ffff8800438a0a00 ffff88002917fdf8 0000000000000000 +[ 1106.400020] 0000000000000000 ffff88002917fde0 ffffffff8116d08a ffff88002917fdc8 +[ 1106.400020] Call Trace: +[ 1106.400020] [] security_inode_setxattr+0x5d/0x6a +[ 1106.400020] [] vfs_setxattr+0x6b/0x9f +[ 1106.400020] [] setxattr+0x122/0x16c +[ 1106.400020] [] ? mnt_want_write+0x21/0x45 +[ 1106.400020] [] ? __sb_start_write+0x10f/0x143 +[ 1106.400020] [] ? mnt_want_write+0x21/0x45 +[ 1106.400020] [] ? __mnt_want_write+0x48/0x4f +[ 1106.400020] [] SyS_setxattr+0x6e/0xb0 +[ 1106.400020] [] system_call_fastpath+0x16/0x1b +[ 1106.400020] Code: c3 0f 1f 44 00 00 55 48 89 e5 41 55 49 89 d5 41 54 49 89 fc 53 48 89 f3 48 c7 c6 d3 36 81 81 48 89 df e8 18 22 04 00 85 c0 75 07 <41> 80 7d 00 02 74 0d 48 89 de 4c 89 e7 e8 5a fe ff ff eb 03 83 +[ 1106.400020] RIP [] evm_inode_setxattr+0x2a/0x48 +[ 1106.400020] RSP +[ 1106.400020] CR2: 0000000000000000 +[ 1106.428061] ---[ end trace ae08331628ba3050 ]--- + +Reported-by: Jan Kara +Signed-off-by: Dmitry Kasatkin +Signed-off-by: Mimi Zohar +Signed-off-by: Greg Kroah-Hartman + +--- + security/integrity/evm/evm_main.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/security/integrity/evm/evm_main.c ++++ b/security/integrity/evm/evm_main.c +@@ -303,9 +303,12 @@ int evm_inode_setxattr(struct dentry *de + { + const struct evm_ima_xattr_data *xattr_data = xattr_value; + +- if ((strcmp(xattr_name, XATTR_NAME_EVM) == 0) +- && (xattr_data->type == EVM_XATTR_HMAC)) +- return -EPERM; ++ if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) { ++ if (!xattr_value_len) ++ return -EINVAL; ++ if (xattr_data->type != EVM_IMA_XATTR_DIGSIG) ++ return -EPERM; ++ } + return evm_protect_xattr(dentry, xattr_name, xattr_value, + xattr_value_len); + } diff --git a/queue-3.14/evm-properly-handle-integrity_noxattrs-evm-status.patch b/queue-3.14/evm-properly-handle-integrity_noxattrs-evm-status.patch new file mode 100644 index 00000000000..63eab0cf9aa --- /dev/null +++ b/queue-3.14/evm-properly-handle-integrity_noxattrs-evm-status.patch @@ -0,0 +1,54 @@ +From 3dcbad52cf18c3c379e96b992d22815439ebbe53 Mon Sep 17 00:00:00 2001 +From: Dmitry Kasatkin +Date: Tue, 2 Sep 2014 16:31:43 +0300 +Subject: evm: properly handle INTEGRITY_NOXATTRS EVM status + +From: Dmitry Kasatkin + +commit 3dcbad52cf18c3c379e96b992d22815439ebbe53 upstream. + +Unless an LSM labels a file during d_instantiate(), newly created +files are not labeled with an initial security.evm xattr, until +the file closes. EVM, before allowing a protected, security xattr +to be written, verifies the existing 'security.evm' value is good. +For newly created files without a security.evm label, this +verification prevents writing any protected, security xattrs, +until the file closes. + +Following is the example when this happens: +fd = open("foo", O_CREAT | O_WRONLY, 0644); +setxattr("foo", "security.SMACK64", value, sizeof(value), 0); +close(fd); + +While INTEGRITY_NOXATTRS status is handled in other places, such +as evm_inode_setattr(), it does not handle it in all cases in +evm_protect_xattr(). By limiting the use of INTEGRITY_NOXATTRS to +newly created files, we can now allow setting "protected" xattrs. + +Changelog: +- limit the use of INTEGRITY_NOXATTRS to IMA identified new files + +Signed-off-by: Dmitry Kasatkin +Signed-off-by: Mimi Zohar +Signed-off-by: Greg Kroah-Hartman + +--- + security/integrity/evm/evm_main.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/security/integrity/evm/evm_main.c ++++ b/security/integrity/evm/evm_main.c +@@ -269,6 +269,13 @@ static int evm_protect_xattr(struct dent + goto out; + } + evm_status = evm_verify_current_integrity(dentry); ++ if (evm_status == INTEGRITY_NOXATTRS) { ++ struct integrity_iint_cache *iint; ++ ++ iint = integrity_iint_find(dentry->d_inode); ++ if (iint && (iint->flags & IMA_NEW_FILE)) ++ return 0; ++ } + out: + if (evm_status != INTEGRITY_PASS) + integrity_audit_msg(AUDIT_INTEGRITY_METADATA, dentry->d_inode, diff --git a/queue-3.14/fix-misuses-of-f_count-in-ppp-and-netlink.patch b/queue-3.14/fix-misuses-of-f_count-in-ppp-and-netlink.patch new file mode 100644 index 00000000000..b9cb2f97293 --- /dev/null +++ b/queue-3.14/fix-misuses-of-f_count-in-ppp-and-netlink.patch @@ -0,0 +1,57 @@ +From 24dff96a37a2ca319e75a74d3929b2de22447ca6 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Wed, 8 Oct 2014 23:44:00 -0400 +Subject: fix misuses of f_count() in ppp and netlink + +From: Al Viro + +commit 24dff96a37a2ca319e75a74d3929b2de22447ca6 upstream. + +we used to check for "nobody else could start doing anything with +that opened file" by checking that refcount was 2 or less - one +for descriptor table and one we'd acquired in fget() on the way to +wherever we are. That was race-prone (somebody else might have +had a reference to descriptor table and do fget() just as we'd +been checking) and it had become flat-out incorrect back when +we switched to fget_light() on those codepaths - unlike fget(), +it doesn't grab an extra reference unless the descriptor table +is shared. The same change allowed a race-free check, though - +we are safe exactly when refcount is less than 2. + +It was a long time ago; pre-2.6.12 for ioctl() (the codepath leading +to ppp one) and 2.6.17 for sendmsg() (netlink one). OTOH, +netlink hadn't grown that check until 3.9 and ppp used to live +in drivers/net, not drivers/net/ppp until 3.1. The bug existed +well before that, though, and the same fix used to apply in old +location of file. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ppp/ppp_generic.c | 2 +- + net/netlink/af_netlink.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ppp/ppp_generic.c ++++ b/drivers/net/ppp/ppp_generic.c +@@ -601,7 +601,7 @@ static long ppp_ioctl(struct file *file, + if (file == ppp->owner) + ppp_shutdown_interface(ppp); + } +- if (atomic_long_read(&file->f_count) <= 2) { ++ if (atomic_long_read(&file->f_count) < 2) { + ppp_release(NULL, file); + err = 0; + } else +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -707,7 +707,7 @@ static int netlink_mmap_sendmsg(struct s + * after validation, the socket and the ring may only be used by a + * single process, otherwise we fall back to copying. + */ +- if (atomic_long_read(&sk->sk_socket->file->f_count) > 2 || ++ if (atomic_long_read(&sk->sk_socket->file->f_count) > 1 || + atomic_read(&nlk->mapped) > 1) + excl = false; + diff --git a/queue-3.14/kill-wbuf_queued-wbuf_dwork_lock.patch b/queue-3.14/kill-wbuf_queued-wbuf_dwork_lock.patch new file mode 100644 index 00000000000..cf8b8e2c7d8 --- /dev/null +++ b/queue-3.14/kill-wbuf_queued-wbuf_dwork_lock.patch @@ -0,0 +1,98 @@ +From 99358a1ca53e8e6ce09423500191396f0e6584d2 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Fri, 1 Aug 2014 20:13:40 +0100 +Subject: [jffs2] kill wbuf_queued/wbuf_dwork_lock + +From: Al Viro + +commit 99358a1ca53e8e6ce09423500191396f0e6584d2 upstream. + +schedule_delayed_work() happening when the work is already pending is +a cheap no-op. Don't bother with ->wbuf_queued logics - it's both +broken (cancelling ->wbuf_dwork leaves it set, as spotted by Jeff Harris) +and pointless. It's cheaper to let schedule_delayed_work() handle that +case. + +Reported-by: Jeff Harris +Tested-by: Jeff Harris +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/jffs2/jffs2_fs_sb.h | 2 -- + fs/jffs2/wbuf.c | 17 ++--------------- + 2 files changed, 2 insertions(+), 17 deletions(-) + +--- a/fs/jffs2/jffs2_fs_sb.h ++++ b/fs/jffs2/jffs2_fs_sb.h +@@ -134,8 +134,6 @@ struct jffs2_sb_info { + struct rw_semaphore wbuf_sem; /* Protects the write buffer */ + + struct delayed_work wbuf_dwork; /* write-buffer write-out work */ +- int wbuf_queued; /* non-zero delayed work is queued */ +- spinlock_t wbuf_dwork_lock; /* protects wbuf_dwork and and wbuf_queued */ + + unsigned char *oobbuf; + int oobavail; /* How many bytes are available for JFFS2 in OOB */ +--- a/fs/jffs2/wbuf.c ++++ b/fs/jffs2/wbuf.c +@@ -1162,10 +1162,6 @@ static void delayed_wbuf_sync(struct wor + struct jffs2_sb_info *c = work_to_sb(work); + struct super_block *sb = OFNI_BS_2SFFJ(c); + +- spin_lock(&c->wbuf_dwork_lock); +- c->wbuf_queued = 0; +- spin_unlock(&c->wbuf_dwork_lock); +- + if (!(sb->s_flags & MS_RDONLY)) { + jffs2_dbg(1, "%s()\n", __func__); + jffs2_flush_wbuf_gc(c, 0); +@@ -1180,14 +1176,9 @@ void jffs2_dirty_trigger(struct jffs2_sb + if (sb->s_flags & MS_RDONLY) + return; + +- spin_lock(&c->wbuf_dwork_lock); +- if (!c->wbuf_queued) { ++ delay = msecs_to_jiffies(dirty_writeback_interval * 10); ++ if (queue_delayed_work(system_long_wq, &c->wbuf_dwork, delay)) + jffs2_dbg(1, "%s()\n", __func__); +- delay = msecs_to_jiffies(dirty_writeback_interval * 10); +- queue_delayed_work(system_long_wq, &c->wbuf_dwork, delay); +- c->wbuf_queued = 1; +- } +- spin_unlock(&c->wbuf_dwork_lock); + } + + int jffs2_nand_flash_setup(struct jffs2_sb_info *c) +@@ -1211,7 +1202,6 @@ int jffs2_nand_flash_setup(struct jffs2_ + + /* Initialise write buffer */ + init_rwsem(&c->wbuf_sem); +- spin_lock_init(&c->wbuf_dwork_lock); + INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); + c->wbuf_pagesize = c->mtd->writesize; + c->wbuf_ofs = 0xFFFFFFFF; +@@ -1251,7 +1241,6 @@ int jffs2_dataflash_setup(struct jffs2_s + + /* Initialize write buffer */ + init_rwsem(&c->wbuf_sem); +- spin_lock_init(&c->wbuf_dwork_lock); + INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); + c->wbuf_pagesize = c->mtd->erasesize; + +@@ -1311,7 +1300,6 @@ int jffs2_nor_wbuf_flash_setup(struct jf + + /* Initialize write buffer */ + init_rwsem(&c->wbuf_sem); +- spin_lock_init(&c->wbuf_dwork_lock); + INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); + + c->wbuf_pagesize = c->mtd->writesize; +@@ -1346,7 +1334,6 @@ int jffs2_ubivol_setup(struct jffs2_sb_i + return 0; + + init_rwsem(&c->wbuf_sem); +- spin_lock_init(&c->wbuf_dwork_lock); + INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync); + + c->wbuf_pagesize = c->mtd->writesize; diff --git a/queue-3.14/libceph-ceph-msgr-workqueue-needs-a-resque-worker.patch b/queue-3.14/libceph-ceph-msgr-workqueue-needs-a-resque-worker.patch new file mode 100644 index 00000000000..f62960f8e56 --- /dev/null +++ b/queue-3.14/libceph-ceph-msgr-workqueue-needs-a-resque-worker.patch @@ -0,0 +1,37 @@ +From f9865f06f7f18c6661c88d0511f05c48612319cc Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Fri, 10 Oct 2014 16:39:05 +0400 +Subject: libceph: ceph-msgr workqueue needs a resque worker + +From: Ilya Dryomov + +commit f9865f06f7f18c6661c88d0511f05c48612319cc upstream. + +Commit f363e45fd118 ("net/ceph: make ceph_msgr_wq non-reentrant") +effectively removed WQ_MEM_RECLAIM flag from ceph_msgr_wq. This is +wrong - libceph is very much a memory reclaim path, so restore it. + +Signed-off-by: Ilya Dryomov +Tested-by: Micha Krause +Reviewed-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + net/ceph/messenger.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/net/ceph/messenger.c ++++ b/net/ceph/messenger.c +@@ -291,7 +291,11 @@ int ceph_msgr_init(void) + if (ceph_msgr_slab_init()) + return -ENOMEM; + +- ceph_msgr_wq = alloc_workqueue("ceph-msgr", 0, 0); ++ /* ++ * The number of active work items is limited by the number of ++ * connections, so leave @max_active at default. ++ */ ++ ceph_msgr_wq = alloc_workqueue("ceph-msgr", WQ_MEM_RECLAIM, 0); + if (ceph_msgr_wq) + return 0; + diff --git a/queue-3.14/missing-data-dependency-barrier-in-prepend_name.patch b/queue-3.14/missing-data-dependency-barrier-in-prepend_name.patch new file mode 100644 index 00000000000..b777fb740f0 --- /dev/null +++ b/queue-3.14/missing-data-dependency-barrier-in-prepend_name.patch @@ -0,0 +1,60 @@ +From 6d13f69444bd3d4888e43f7756449748f5a98bad Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Mon, 29 Sep 2014 14:46:30 -0400 +Subject: missing data dependency barrier in prepend_name() + +From: Al Viro + +commit 6d13f69444bd3d4888e43f7756449748f5a98bad upstream. + +AFAICS, prepend_name() is broken on SMP alpha. Disclaimer: I don't have +SMP alpha boxen to reproduce it on. However, it really looks like the race +is real. + +CPU1: d_path() on /mnt/ramfs/<255-character>/foo +CPU2: mv /mnt/ramfs/<255-character> /mnt/ramfs/<63-character> + +CPU2 does d_alloc(), which allocates an external name, stores the name there +including terminating NUL, does smp_wmb() and stores its address in +dentry->d_name.name. It proceeds to d_add(dentry, NULL) and d_move() +old dentry over to that. ->d_name.name value ends up in that dentry. + +In the meanwhile, CPU1 gets to prepend_name() for that dentry. It fetches +->d_name.name and ->d_name.len; the former ends up pointing to new name +(64-byte kmalloc'ed array), the latter - 255 (length of the old name). +Nothing to force the ordering there, and normally that would be OK, since we'd +run into the terminating NUL and stop. Except that it's alpha, and we'd need +a data dependency barrier to guarantee that we see that store of NUL +__d_alloc() has done. In a similar situation dentry_cmp() would survive; it +does explicit smp_read_barrier_depends() after fetching ->d_name.name. +prepend_name() doesn't and it risks walking past the end of kmalloc'ed object +and possibly oops due to taking a page fault in kernel mode. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/dcache.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -2824,6 +2824,9 @@ static int prepend(char **buffer, int *b + * the beginning of the name. The sequence number check at the caller will + * retry it again when a d_move() does happen. So any garbage in the buffer + * due to mismatched pointer and length will be discarded. ++ * ++ * Data dependency barrier is needed to make sure that we see that terminating ++ * NUL. Alpha strikes again, film at 11... + */ + static int prepend_name(char **buffer, int *buflen, struct qstr *name) + { +@@ -2831,6 +2834,8 @@ static int prepend_name(char **buffer, i + u32 dlen = ACCESS_ONCE(name->len); + char *p; + ++ smp_read_barrier_depends(); ++ + *buflen -= dlen + 1; + if (*buflen < 0) + return -ENAMETOOLONG; diff --git a/queue-3.14/sched-use-dl_bw_of-under-rcu-read-lock.patch b/queue-3.14/sched-use-dl_bw_of-under-rcu-read-lock.patch new file mode 100644 index 00000000000..88c53c8afc8 --- /dev/null +++ b/queue-3.14/sched-use-dl_bw_of-under-rcu-read-lock.patch @@ -0,0 +1,80 @@ +From 66339c31bc3978d5fff9c4b4cb590a861def4db2 Mon Sep 17 00:00:00 2001 +From: Kirill Tkhai +Date: Mon, 22 Sep 2014 22:36:24 +0400 +Subject: sched: Use dl_bw_of() under RCU read lock + +From: Kirill Tkhai + +commit 66339c31bc3978d5fff9c4b4cb590a861def4db2 upstream. + +dl_bw_of() dereferences rq->rd which has to have RCU read lock held. +Probability of use-after-free isn't zero here. + +Also add lockdep assert into dl_bw_cpus(). + +Signed-off-by: Kirill Tkhai +Signed-off-by: Peter Zijlstra (Intel) +Cc: Paul E. McKenney +Cc: Linus Torvalds +Link: http://lkml.kernel.org/r/20140922183624.11015.71558.stgit@localhost +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/sched/core.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -1895,6 +1895,8 @@ unsigned long to_ratio(u64 period, u64 r + #ifdef CONFIG_SMP + inline struct dl_bw *dl_bw_of(int i) + { ++ rcu_lockdep_assert(rcu_read_lock_sched_held(), ++ "sched RCU must be held"); + return &cpu_rq(i)->rd->dl_bw; + } + +@@ -1903,6 +1905,8 @@ static inline int dl_bw_cpus(int i) + struct root_domain *rd = cpu_rq(i)->rd; + int cpus = 0; + ++ rcu_lockdep_assert(rcu_read_lock_sched_held(), ++ "sched RCU must be held"); + for_each_cpu_and(i, rd->span, cpu_active_mask) + cpus++; + +@@ -7458,6 +7462,8 @@ static int sched_dl_global_constraints(v + int cpu, ret = 0; + unsigned long flags; + ++ rcu_read_lock(); ++ + /* + * Here we want to check the bandwidth not being set to some + * value smaller than the currently allocated bandwidth in +@@ -7479,6 +7485,8 @@ static int sched_dl_global_constraints(v + break; + } + ++ rcu_read_unlock(); ++ + return ret; + } + +@@ -7494,6 +7502,7 @@ static void sched_dl_do_global(void) + if (global_rt_runtime() != RUNTIME_INF) + new_bw = to_ratio(global_rt_period(), global_rt_runtime()); + ++ rcu_read_lock(); + /* + * FIXME: As above... + */ +@@ -7504,6 +7513,7 @@ static void sched_dl_do_global(void) + dl_b->bw = new_bw; + raw_spin_unlock_irqrestore(&dl_b->lock, flags); + } ++ rcu_read_unlock(); + } + + static int sched_rt_global_validate(void) diff --git a/queue-3.14/series b/queue-3.14/series index dcca329802c..8c00775a302 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -33,3 +33,12 @@ x86-fpu-shift-drop_init_fpu-from-save_xstate_sig-to-handle_signal.patch x86_64-entry-filter-rflags.nt-on-entry-from-userspace.patch x86_64-entry-fix-out-of-bounds-read-on-sysenter.patch x86-pageattr-prevent-overflow-in-slow_virt_to_phys-for-x86_pae.patch +evm-properly-handle-integrity_noxattrs-evm-status.patch +evm-check-xattr-value-length-and-type-in-evm_inode_setxattr.patch +alsa-pcm-zero-clear-reserved-fields-of-pcm-status-ioctl-in-compat-mode.patch +missing-data-dependency-barrier-in-prepend_name.patch +kill-wbuf_queued-wbuf_dwork_lock.patch +fix-misuses-of-f_count-in-ppp-and-netlink.patch +libceph-ceph-msgr-workqueue-needs-a-resque-worker.patch +sched-use-dl_bw_of-under-rcu-read-lock.patch +um-ubd-fix-for-processes-stuck-in-d-state-forever.patch diff --git a/queue-3.14/um-ubd-fix-for-processes-stuck-in-d-state-forever.patch b/queue-3.14/um-ubd-fix-for-processes-stuck-in-d-state-forever.patch new file mode 100644 index 00000000000..eeca1d83a46 --- /dev/null +++ b/queue-3.14/um-ubd-fix-for-processes-stuck-in-d-state-forever.patch @@ -0,0 +1,46 @@ +From 2a2361228c5e6d8c1733f00653481de918598e50 Mon Sep 17 00:00:00 2001 +From: Thorsten Knabe +Date: Sat, 23 Aug 2014 15:47:38 +0200 +Subject: um: ubd: Fix for processes stuck in D state forever + +From: Thorsten Knabe + +commit 2a2361228c5e6d8c1733f00653481de918598e50 upstream. + +Starting with Linux 3.12 processes get stuck in D state forever in +UserModeLinux under sync heavy workloads. This bug was introduced by +commit 805f11a0d5 (um: ubd: Add REQ_FLUSH suppport). +Fix bug by adding a check if FLUSH request was successfully submitted to +the I/O thread and keeping the FLUSH request on the request queue on +submission failures. + +Fixes: 805f11a0d5 (um: ubd: Add REQ_FLUSH suppport) +Signed-off-by: Thorsten Knabe +Signed-off-by: Richard Weinberger +Signed-off-by: Greg Kroah-Hartman + +--- + arch/um/drivers/ubd_kern.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/arch/um/drivers/ubd_kern.c ++++ b/arch/um/drivers/ubd_kern.c +@@ -1277,7 +1277,7 @@ static void do_ubd_request(struct reques + + while(1){ + struct ubd *dev = q->queuedata; +- if(dev->end_sg == 0){ ++ if(dev->request == NULL){ + struct request *req = blk_fetch_request(q); + if(req == NULL) + return; +@@ -1299,7 +1299,8 @@ static void do_ubd_request(struct reques + return; + } + prepare_flush_request(req, io_req); +- submit_request(io_req, dev); ++ if (submit_request(io_req, dev) == false) ++ return; + } + + while(dev->start_sg < dev->end_sg){