]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 3 Jul 2017 08:51:32 +0000 (10:51 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 3 Jul 2017 08:51:32 +0000 (10:51 +0200)
added patches:
block-fix-module-reference-leak-on-put_disk-call-for-cgroups-throttle.patch
sysctl-enable-strict-writes.patch
usb-gadget-f_fs-fix-possibe-deadlock.patch

queue-4.4/block-fix-module-reference-leak-on-put_disk-call-for-cgroups-throttle.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/sysctl-enable-strict-writes.patch [new file with mode: 0644]
queue-4.4/usb-gadget-f_fs-fix-possibe-deadlock.patch [new file with mode: 0644]

diff --git a/queue-4.4/block-fix-module-reference-leak-on-put_disk-call-for-cgroups-throttle.patch b/queue-4.4/block-fix-module-reference-leak-on-put_disk-call-for-cgroups-throttle.patch
new file mode 100644 (file)
index 0000000..270b41d
--- /dev/null
@@ -0,0 +1,99 @@
+From 39a169b62b415390398291080dafe63aec751e0a Mon Sep 17 00:00:00 2001
+From: Roman Pen <roman.penyaev@profitbricks.com>
+Date: Tue, 9 Feb 2016 12:33:35 -0700
+Subject: block: fix module reference leak on put_disk() call for cgroups throttle
+
+From: Roman Pen <roman.penyaev@profitbricks.com>
+
+commit 39a169b62b415390398291080dafe63aec751e0a upstream.
+
+get_disk(),get_gendisk() calls have non explicit side effect: they
+increase the reference on the disk owner module.
+
+The following is the correct sequence how to get a disk reference and
+to put it:
+
+    disk = get_gendisk(...);
+
+    /* use disk */
+
+    owner = disk->fops->owner;
+    put_disk(disk);
+    module_put(owner);
+
+fs/block_dev.c is aware of this required module_put() call, but f.e.
+blkg_conf_finish(), which is located in block/blk-cgroup.c, does not put
+a module reference.  To see a leakage in action cgroups throttle config
+can be used.  In the following script I'm removing throttle for /dev/ram0
+(actually this is NOP, because throttle was never set for this device):
+
+    # lsmod | grep brd
+    brd                     5175  0
+    # i=100; while [ $i -gt 0 ]; do echo "1:0 0" > \
+        /sys/fs/cgroup/blkio/blkio.throttle.read_bps_device; i=$(($i - 1)); \
+    done
+    # lsmod | grep brd
+    brd                     5175  100
+
+Now brd module has 100 references.
+
+The issue is fixed by calling module_put() just right away put_disk().
+
+Signed-off-by: Roman Pen <roman.penyaev@profitbricks.com>
+Cc: Gi-Oh Kim <gi-oh.kim@profitbricks.com>
+Cc: Tejun Heo <tj@kernel.org>
+Cc: Jens Axboe <axboe@kernel.dk>
+Cc: linux-block@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Signed-off-by: Jens Axboe <axboe@fb.com>
+Cc: Sumit Semwal <sumit.semwal@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ block/blk-cgroup.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/block/blk-cgroup.c
++++ b/block/blk-cgroup.c
+@@ -788,6 +788,7 @@ int blkg_conf_prep(struct blkcg *blkcg,
+ {
+       struct gendisk *disk;
+       struct blkcg_gq *blkg;
++      struct module *owner;
+       unsigned int major, minor;
+       int key_len, part, ret;
+       char *body;
+@@ -804,7 +805,9 @@ int blkg_conf_prep(struct blkcg *blkcg,
+       if (!disk)
+               return -ENODEV;
+       if (part) {
++              owner = disk->fops->owner;
+               put_disk(disk);
++              module_put(owner);
+               return -ENODEV;
+       }
+@@ -820,7 +823,9 @@ int blkg_conf_prep(struct blkcg *blkcg,
+               ret = PTR_ERR(blkg);
+               rcu_read_unlock();
+               spin_unlock_irq(disk->queue->queue_lock);
++              owner = disk->fops->owner;
+               put_disk(disk);
++              module_put(owner);
+               /*
+                * If queue was bypassing, we should retry.  Do so after a
+                * short msleep().  It isn't strictly necessary but queue
+@@ -851,9 +856,13 @@ EXPORT_SYMBOL_GPL(blkg_conf_prep);
+ void blkg_conf_finish(struct blkg_conf_ctx *ctx)
+       __releases(ctx->disk->queue->queue_lock) __releases(rcu)
+ {
++      struct module *owner;
++
+       spin_unlock_irq(ctx->disk->queue->queue_lock);
+       rcu_read_unlock();
++      owner = ctx->disk->fops->owner;
+       put_disk(ctx->disk);
++      module_put(owner);
+ }
+ EXPORT_SYMBOL_GPL(blkg_conf_finish);
index 33e198ede43b55316615e6340b8b235575db2760..b8674a2f1c59276e2e3475bce8575ab8ed8e81ed 100644 (file)
@@ -25,3 +25,6 @@ mips-fix-irq-tracing-lockdep-when-rescheduling.patch
 alsa-hda-fix-endless-loop-of-codec-configure.patch
 alsa-hda-set-input_path-bitmap-to-zero-after-moving-it-to-new-place.patch
 drm-vmwgfx-free-hash-table-allocated-by-cmdbuf-managed-res-mgr.patch
+usb-gadget-f_fs-fix-possibe-deadlock.patch
+sysctl-enable-strict-writes.patch
+block-fix-module-reference-leak-on-put_disk-call-for-cgroups-throttle.patch
diff --git a/queue-4.4/sysctl-enable-strict-writes.patch b/queue-4.4/sysctl-enable-strict-writes.patch
new file mode 100644 (file)
index 0000000..6ee4730
--- /dev/null
@@ -0,0 +1,65 @@
+From 41662f5cc55335807d39404371cfcbb1909304c4 Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook@chromium.org>
+Date: Wed, 20 Jan 2016 15:00:45 -0800
+Subject: sysctl: enable strict writes
+
+From: Kees Cook <keescook@chromium.org>
+
+commit 41662f5cc55335807d39404371cfcbb1909304c4 upstream.
+
+SYSCTL_WRITES_WARN was added in commit f4aacea2f5d1 ("sysctl: allow for
+strict write position handling"), and released in v3.16 in August of
+2014.  Since then I can find only 1 instance of non-zero offset
+writing[1], and it was fixed immediately in CRIU[2].  As such, it
+appears safe to flip this to the strict state now.
+
+[1] https://www.google.com/search?q="when%20file%20position%20was%20not%200"
+[2] http://lists.openvz.org/pipermail/criu/2015-April/019819.html
+
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Cc: "Eric W. Biederman" <ebiederm@xmission.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Sumit Semwal <sumit.semwal@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ Documentation/sysctl/kernel.txt |   15 +++++++--------
+ kernel/sysctl.c                 |    2 +-
+ 2 files changed, 8 insertions(+), 9 deletions(-)
+
+--- a/Documentation/sysctl/kernel.txt
++++ b/Documentation/sysctl/kernel.txt
+@@ -810,14 +810,13 @@ via the /proc/sys interface:
+        Each write syscall must fully contain the sysctl value to be
+        written, and multiple writes on the same sysctl file descriptor
+        will rewrite the sysctl value, regardless of file position.
+-   0 - (default) Same behavior as above, but warn about processes that
+-       perform writes to a sysctl file descriptor when the file position
+-       is not 0.
+-   1 - Respect file position when writing sysctl strings. Multiple writes
+-       will append to the sysctl value buffer. Anything past the max length
+-       of the sysctl value buffer will be ignored. Writes to numeric sysctl
+-       entries must always be at file position 0 and the value must be
+-       fully contained in the buffer sent in the write syscall.
++   0 - Same behavior as above, but warn about processes that perform writes
++       to a sysctl file descriptor when the file position is not 0.
++   1 - (default) Respect file position when writing sysctl strings. Multiple
++       writes will append to the sysctl value buffer. Anything past the max
++       length of the sysctl value buffer will be ignored. Writes to numeric
++       sysctl entries must always be at file position 0 and the value must
++       be fully contained in the buffer sent in the write syscall.
+ ==============================================================
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -174,7 +174,7 @@ extern int no_unaligned_warning;
+ #define SYSCTL_WRITES_WARN     0
+ #define SYSCTL_WRITES_STRICT   1
+-static int sysctl_writes_strict = SYSCTL_WRITES_WARN;
++static int sysctl_writes_strict = SYSCTL_WRITES_STRICT;
+ static int proc_do_cad_pid(struct ctl_table *table, int write,
+                 void __user *buffer, size_t *lenp, loff_t *ppos);
diff --git a/queue-4.4/usb-gadget-f_fs-fix-possibe-deadlock.patch b/queue-4.4/usb-gadget-f_fs-fix-possibe-deadlock.patch
new file mode 100644 (file)
index 0000000..d10cedd
--- /dev/null
@@ -0,0 +1,138 @@
+From b3ce3ce02d146841af012d08506b4071db8ffde3 Mon Sep 17 00:00:00 2001
+From: Baolin Wang <baolin.wang@linaro.org>
+Date: Thu, 8 Dec 2016 19:55:22 +0800
+Subject: usb: gadget: f_fs: Fix possibe deadlock
+
+From: Baolin Wang <baolin.wang@linaro.org>
+
+commit b3ce3ce02d146841af012d08506b4071db8ffde3 upstream.
+
+When system try to close /dev/usb-ffs/adb/ep0 on one core, at the same
+time another core try to attach new UDC, which will cause deadlock as
+below scenario. Thus we should release ffs lock before issuing
+unregister_gadget_item().
+
+[   52.642225] c1 ======================================================
+[   52.642228] c1 [ INFO: possible circular locking dependency detected ]
+[   52.642236] c1 4.4.6+ #1 Tainted: G        W  O
+[   52.642241] c1 -------------------------------------------------------
+[   52.642245] c1 usb ffs open/2808 is trying to acquire lock:
+[   52.642270] c0  (udc_lock){+.+.+.}, at: [<ffffffc00065aeec>]
+               usb_gadget_unregister_driver+0x3c/0xc8
+[   52.642272] c1  but task is already holding lock:
+[   52.642283] c0  (ffs_lock){+.+.+.}, at: [<ffffffc00066b244>]
+               ffs_data_clear+0x30/0x140
+[   52.642285] c1 which lock already depends on the new lock.
+[   52.642287] c1
+               the existing dependency chain (in reverse order) is:
+[   52.642295] c0
+              -> #1 (ffs_lock){+.+.+.}:
+[   52.642307] c0        [<ffffffc00012340c>] __lock_acquire+0x20f0/0x2238
+[   52.642314] c0        [<ffffffc000123b54>] lock_acquire+0xe4/0x298
+[   52.642322] c0        [<ffffffc000aaf6e8>] mutex_lock_nested+0x7c/0x3cc
+[   52.642328] c0        [<ffffffc00066f7bc>] ffs_func_bind+0x504/0x6e8
+[   52.642334] c0        [<ffffffc000654004>] usb_add_function+0x84/0x184
+[   52.642340] c0        [<ffffffc000658ca4>] configfs_composite_bind+0x264/0x39c
+[   52.642346] c0        [<ffffffc00065b348>] udc_bind_to_driver+0x58/0x11c
+[   52.642352] c0        [<ffffffc00065b49c>] usb_udc_attach_driver+0x90/0xc8
+[   52.642358] c0        [<ffffffc0006598e0>] gadget_dev_desc_UDC_store+0xd4/0x128
+[   52.642369] c0        [<ffffffc0002c14e8>] configfs_write_file+0xd0/0x13c
+[   52.642376] c0        [<ffffffc00023c054>] vfs_write+0xb8/0x214
+[   52.642381] c0        [<ffffffc00023cad4>] SyS_write+0x54/0xb0
+[   52.642388] c0        [<ffffffc000085ff0>] el0_svc_naked+0x24/0x28
+[   52.642395] c0
+              -> #0 (udc_lock){+.+.+.}:
+[   52.642401] c0        [<ffffffc00011e3d0>] print_circular_bug+0x84/0x2e4
+[   52.642407] c0        [<ffffffc000123454>] __lock_acquire+0x2138/0x2238
+[   52.642412] c0        [<ffffffc000123b54>] lock_acquire+0xe4/0x298
+[   52.642420] c0        [<ffffffc000aaf6e8>] mutex_lock_nested+0x7c/0x3cc
+[   52.642427] c0        [<ffffffc00065aeec>] usb_gadget_unregister_driver+0x3c/0xc8
+[   52.642432] c0        [<ffffffc00065995c>] unregister_gadget_item+0x28/0x44
+[   52.642439] c0        [<ffffffc00066b34c>] ffs_data_clear+0x138/0x140
+[   52.642444] c0        [<ffffffc00066b374>] ffs_data_reset+0x20/0x6c
+[   52.642450] c0        [<ffffffc00066efd0>] ffs_data_closed+0xac/0x12c
+[   52.642454] c0        [<ffffffc00066f070>] ffs_ep0_release+0x20/0x2c
+[   52.642460] c0        [<ffffffc00023dbe4>] __fput+0xb0/0x1f4
+[   52.642466] c0        [<ffffffc00023dd9c>] ____fput+0x20/0x2c
+[   52.642473] c0        [<ffffffc0000ee944>] task_work_run+0xb4/0xe8
+[   52.642482] c0        [<ffffffc0000cd45c>] do_exit+0x360/0xb9c
+[   52.642487] c0        [<ffffffc0000cf228>] do_group_exit+0x4c/0xb0
+[   52.642494] c0        [<ffffffc0000dd3c8>] get_signal+0x380/0x89c
+[   52.642501] c0        [<ffffffc00008a8f0>] do_signal+0x154/0x518
+[   52.642507] c0        [<ffffffc00008af00>] do_notify_resume+0x70/0x78
+[   52.642512] c0        [<ffffffc000085ee8>] work_pending+0x1c/0x20
+[   52.642514] c1
+              other info that might help us debug this:
+[   52.642517] c1  Possible unsafe locking scenario:
+[   52.642518] c1        CPU0                    CPU1
+[   52.642520] c1        ----                    ----
+[   52.642525] c0   lock(ffs_lock);
+[   52.642529] c0                                lock(udc_lock);
+[   52.642533] c0                                lock(ffs_lock);
+[   52.642537] c0   lock(udc_lock);
+[   52.642539] c1
+                      *** DEADLOCK ***
+[   52.642543] c1 1 lock held by usb ffs open/2808:
+[   52.642555] c0  #0:  (ffs_lock){+.+.+.}, at: [<ffffffc00066b244>]
+               ffs_data_clear+0x30/0x140
+[   52.642557] c1 stack backtrace:
+[   52.642563] c1 CPU: 1 PID: 2808 Comm: usb ffs open Tainted: G
+[   52.642565] c1 Hardware name: Spreadtrum SP9860g Board (DT)
+[   52.642568] c1 Call trace:
+[   52.642573] c1 [<ffffffc00008b430>] dump_backtrace+0x0/0x170
+[   52.642577] c1 [<ffffffc00008b5c0>] show_stack+0x20/0x28
+[   52.642583] c1 [<ffffffc000422694>] dump_stack+0xa8/0xe0
+[   52.642587] c1 [<ffffffc00011e548>] print_circular_bug+0x1fc/0x2e4
+[   52.642591] c1 [<ffffffc000123454>] __lock_acquire+0x2138/0x2238
+[   52.642595] c1 [<ffffffc000123b54>] lock_acquire+0xe4/0x298
+[   52.642599] c1 [<ffffffc000aaf6e8>] mutex_lock_nested+0x7c/0x3cc
+[   52.642604] c1 [<ffffffc00065aeec>] usb_gadget_unregister_driver+0x3c/0xc8
+[   52.642608] c1 [<ffffffc00065995c>] unregister_gadget_item+0x28/0x44
+[   52.642613] c1 [<ffffffc00066b34c>] ffs_data_clear+0x138/0x140
+[   52.642618] c1 [<ffffffc00066b374>] ffs_data_reset+0x20/0x6c
+[   52.642621] c1 [<ffffffc00066efd0>] ffs_data_closed+0xac/0x12c
+[   52.642625] c1 [<ffffffc00066f070>] ffs_ep0_release+0x20/0x2c
+[   52.642629] c1 [<ffffffc00023dbe4>] __fput+0xb0/0x1f4
+[   52.642633] c1 [<ffffffc00023dd9c>] ____fput+0x20/0x2c
+[   52.642636] c1 [<ffffffc0000ee944>] task_work_run+0xb4/0xe8
+[   52.642640] c1 [<ffffffc0000cd45c>] do_exit+0x360/0xb9c
+[   52.642644] c1 [<ffffffc0000cf228>] do_group_exit+0x4c/0xb0
+[   52.642647] c1 [<ffffffc0000dd3c8>] get_signal+0x380/0x89c
+[   52.642651] c1 [<ffffffc00008a8f0>] do_signal+0x154/0x518
+[   52.642656] c1 [<ffffffc00008af00>] do_notify_resume+0x70/0x78
+[   52.642659] c1 [<ffffffc000085ee8>] work_pending+0x1c/0x20
+
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Cc: Jerry Zhang <zhangjerry@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/function/f_fs.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_fs.c
++++ b/drivers/usb/gadget/function/f_fs.c
+@@ -3463,6 +3463,7 @@ static void ffs_closed(struct ffs_data *
+ {
+       struct ffs_dev *ffs_obj;
+       struct f_fs_opts *opts;
++      struct config_item *ci;
+       ENTER();
+       ffs_dev_lock();
+@@ -3486,8 +3487,11 @@ static void ffs_closed(struct ffs_data *
+           || !atomic_read(&opts->func_inst.group.cg_item.ci_kref.refcount))
+               goto done;
+-      unregister_gadget_item(ffs_obj->opts->
+-                             func_inst.group.cg_item.ci_parent->ci_parent);
++      ci = opts->func_inst.group.cg_item.ci_parent->ci_parent;
++      ffs_dev_unlock();
++
++      unregister_gadget_item(ci);
++      return;
+ done:
+       ffs_dev_unlock();
+ }