]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 5 Feb 2017 10:45:12 +0000 (11:45 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 5 Feb 2017 10:45:12 +0000 (11:45 +0100)
added patches:
fs-break-out-of-iomap_file_buffered_write-on-fatal-signals.patch

queue-4.9/firmware-fix-null-pointer-dereference-in-__fw_load_abort.patch [deleted file]
queue-4.9/fs-break-out-of-iomap_file_buffered_write-on-fatal-signals.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/firmware-fix-null-pointer-dereference-in-__fw_load_abort.patch b/queue-4.9/firmware-fix-null-pointer-dereference-in-__fw_load_abort.patch
deleted file mode 100644 (file)
index 2d6bc4b..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-From 191e885a2e130e639bb0c8ee350d7047294f2ce6 Mon Sep 17 00:00:00 2001
-From: "Luis R. Rodriguez" <mcgrof@kernel.org>
-Date: Wed, 25 Jan 2017 10:31:52 -0800
-Subject: firmware: fix NULL pointer dereference in __fw_load_abort()
-
-From: Luis R. Rodriguez <mcgrof@kernel.org>
-
-commit 191e885a2e130e639bb0c8ee350d7047294f2ce6 upstream.
-
-Since commit 5d47ec02c37ea6 ("firmware: Correct handling of
-fw_state_wait() return value") fw_load_abort() could be called twice and
-lead us to a kernel crash. This happens only when the firmware fallback
-mechanism (regular or custom) is used. The fallback mechanism exposes a
-sysfs interface for userspace to upload a file and notify the kernel
-when the file is loaded and ready, or to cancel an upload by echo'ing -1
-into on the loading file:
-
-echo -n "-1" > /sys/$DEVPATH/loading
-
-This will call fw_load_abort(). Some distributions actually have a udev
-rule in place to *always* immediately cancel all firmware fallback
-mechanism requests (Debian), they have:
-
-  $ cat /lib/udev/rules.d/50-firmware.rules
-  # stub for immediately telling the kernel that userspace firmware loading
-  # failed; necessary to avoid long timeouts with CONFIG_FW_LOADER_USER_HELPER=y
-  SUBSYSTEM=="firmware", ACTION=="add", ATTR{loading}="-1
-
-Distributions with this udev rule would run into this crash only if the
-fallback mechanism is used. Since most distributions disable by default
-using the fallback mechanism (CONFIG_FW_LOADER_USER_HELPER_FALLBACK),
-this would typicaly mean only 2 drivers which *require* the fallback
-mechanism could typically incur a crash: drivers/firmware/dell_rbu.c and
-the drivers/leds/leds-lp55xx-common.c driver. Distributions enabling
-CONFIG_FW_LOADER_USER_HELPER_FALLBACK by default are obviously more
-exposed to this crash.
-
-The crash happens because after commit 5b029624948d ("firmware: do not
-use fw_lock for fw_state protection") and subsequent fix commit
-5d47ec02c37ea6 ("firmware: Correct handling of fw_state_wait() return
-value") a race can happen between this cancelation and the firmware
-fw_state_wait_timeout() being woken up after a state change with which
-fw_load_abort() as that calls swake_up(). Upon error
-fw_state_wait_timeout() will also again call fw_load_abort() and trigger
-a null reference.
-
-At first glance we could just fix this with a !buf check on
-fw_load_abort() before accessing buf->fw_st, however there is a logical
-issue in having a state machine used for the fallback mechanism and
-preventing access from it once we abort as its inside the buf
-(buf->fw_st).
-
-The firmware_class.c code is setting the buf to NULL to annotate an
-abort has occurred. Replace this mechanism by simply using the state
-check instead. All the other code in place already uses similar checks
-for aborting as well so no further changes are needed.
-
-An oops can be reproduced with the new fw_fallback.sh fallback mechanism
-cancellation test. Either cancelling the fallback mechanism or the
-custom fallback mechanism triggers a crash.
-
-mcgrof@piggy ~/linux-next/tools/testing/selftests/firmware
-(git::20170111-fw-fixes)$ sudo ./fw_fallback.sh
-
-./fw_fallback.sh: timeout works
-./fw_fallback.sh: firmware comparison works
-./fw_fallback.sh: fallback mechanism works
-
-[ this then sits here when it is trying the cancellation test ]
-
-Kernel log:
-
-test_firmware: loading 'nope-test-firmware.bin'
-misc test_firmware: Direct firmware load for nope-test-firmware.bin failed with error -2
-misc test_firmware: Falling back to user helper
-BUG: unable to handle kernel NULL pointer dereference at 0000000000000038
-IP: _request_firmware+0xa27/0xad0
-PGD 0
-
-Oops: 0000 [#1] SMP
-Modules linked in: test_firmware(E) ... etc ...
-CPU: 1 PID: 1396 Comm: fw_fallback.sh Tainted: G        W E   4.10.0-rc3-next-20170111+ #30
-Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.10.1-0-g8891697-prebuilt.qemu-project.org 04/01/2014
-task: ffff9740b27f4340 task.stack: ffffbb15c0bc8000
-RIP: 0010:_request_firmware+0xa27/0xad0
-RSP: 0018:ffffbb15c0bcbd10 EFLAGS: 00010246
-RAX: 00000000fffffffe RBX: ffff9740afe5aa80 RCX: 0000000000000000
-RDX: ffff9740b27f4340 RSI: 0000000000000283 RDI: 0000000000000000
-RBP: ffffbb15c0bcbd90 R08: ffffbb15c0bcbcd8 R09: 0000000000000000
-R10: 0000000894a0d4b1 R11: 000000000000008c R12: ffffffffc0312480
-R13: 0000000000000005 R14: ffff9740b1c32400 R15: 00000000000003e8
-FS:  00007f8604422700(0000) GS:ffff9740bfc80000(0000) knlGS:0000000000000000
-CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
-CR2: 0000000000000038 CR3: 000000012164c000 CR4: 00000000000006e0
-Call Trace:
- request_firmware+0x37/0x50
- trigger_request_store+0x79/0xd0 [test_firmware]
- dev_attr_store+0x18/0x30
- sysfs_kf_write+0x37/0x40
- kernfs_fop_write+0x110/0x1a0
- __vfs_write+0x37/0x160
- ? _cond_resched+0x1a/0x50
- vfs_write+0xb5/0x1a0
- SyS_write+0x55/0xc0
- ? trace_do_page_fault+0x37/0xd0
- entry_SYSCALL_64_fastpath+0x1e/0xad
-RIP: 0033:0x7f8603f49620
-RSP: 002b:00007fff6287b788 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
-RAX: ffffffffffffffda RBX: 000055c307b110a0 RCX: 00007f8603f49620
-RDX: 0000000000000016 RSI: 000055c3084d8a90 RDI: 0000000000000001
-RBP: 0000000000000016 R08: 000000000000c0ff R09: 000055c3084d6336
-R10: 000055c307b108b0 R11: 0000000000000246 R12: 000055c307b13c80
-R13: 000055c3084d6320 R14: 0000000000000000 R15: 00007fff6287b950
-Code: 9f 64 84 e8 9c 61 fe ff b8 f4 ff ff ff e9 6b f9 ff
-ff 48 c7 c7 40 6b 8d 84 89 45 a8 e8 43 84 18 00 49 8b be 00 03 00 00 8b
-45 a8 <83> 7f 38 02 74 08 e8 6e ec ff ff 8b 45 a8 49 c7 86 00 03 00 00
-RIP: _request_firmware+0xa27/0xad0 RSP: ffffbb15c0bcbd10
-CR2: 0000000000000038
----[ end trace 6d94ac339c133e6f ]---
-
-Fixes: 5d47ec02c37e ("firmware: Correct handling of fw_state_wait() return value")
-Reported-and-Tested-by: Jakub Kicinski <jakub.kicinski@netronome.com>
-Reported-and-Tested-by: Patrick Bruenn <p.bruenn@beckhoff.com>
-Reported-by: Chris Wilson <chris@chris-wilson.co.uk>
-Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- drivers/base/firmware_class.c |    5 +----
- 1 file changed, 1 insertion(+), 4 deletions(-)
-
---- a/drivers/base/firmware_class.c
-+++ b/drivers/base/firmware_class.c
-@@ -491,9 +491,6 @@ static void fw_load_abort(struct firmwar
-       struct firmware_buf *buf = fw_priv->buf;
-       __fw_load_abort(buf);
--
--      /* avoid user action after loading abort */
--      fw_priv->buf = NULL;
- }
- #define is_fw_load_aborted(buf)       \
-@@ -647,7 +644,7 @@ static ssize_t firmware_loading_store(st
-       mutex_lock(&fw_lock);
-       fw_buf = fw_priv->buf;
--      if (!fw_buf)
-+      if (fw_state_is_aborted(&fw_buf->fw_st))
-               goto out;
-       switch (loading) {
diff --git a/queue-4.9/fs-break-out-of-iomap_file_buffered_write-on-fatal-signals.patch b/queue-4.9/fs-break-out-of-iomap_file_buffered_write-on-fatal-signals.patch
new file mode 100644 (file)
index 0000000..bb9c2cb
--- /dev/null
@@ -0,0 +1,88 @@
+From d1908f52557b3230fbd63c0429f3b4b748bf2b6d Mon Sep 17 00:00:00 2001
+From: Michal Hocko <mhocko@suse.com>
+Date: Fri, 3 Feb 2017 13:13:26 -0800
+Subject: fs: break out of iomap_file_buffered_write on fatal signals
+
+From: Michal Hocko <mhocko@suse.com>
+
+commit d1908f52557b3230fbd63c0429f3b4b748bf2b6d upstream.
+
+Tetsuo has noticed that an OOM stress test which performs large write
+requests can cause the full memory reserves depletion.  He has tracked
+this down to the following path
+
+       __alloc_pages_nodemask+0x436/0x4d0
+       alloc_pages_current+0x97/0x1b0
+       __page_cache_alloc+0x15d/0x1a0          mm/filemap.c:728
+       pagecache_get_page+0x5a/0x2b0           mm/filemap.c:1331
+       grab_cache_page_write_begin+0x23/0x40   mm/filemap.c:2773
+       iomap_write_begin+0x50/0xd0             fs/iomap.c:118
+       iomap_write_actor+0xb5/0x1a0            fs/iomap.c:190
+       ? iomap_write_end+0x80/0x80             fs/iomap.c:150
+       iomap_apply+0xb3/0x130                  fs/iomap.c:79
+       iomap_file_buffered_write+0x68/0xa0     fs/iomap.c:243
+       ? iomap_write_end+0x80/0x80
+       xfs_file_buffered_aio_write+0x132/0x390 [xfs]
+       ? remove_wait_queue+0x59/0x60
+       xfs_file_write_iter+0x90/0x130 [xfs]
+       __vfs_write+0xe5/0x140
+       vfs_write+0xc7/0x1f0
+       ? syscall_trace_enter+0x1d0/0x380
+       SyS_write+0x58/0xc0
+       do_syscall_64+0x6c/0x200
+       entry_SYSCALL64_slow_path+0x25/0x25
+
+the oom victim has access to all memory reserves to make a forward
+progress to exit easier.  But iomap_file_buffered_write and other
+callers of iomap_apply loop to complete the full request.  We need to
+check for fatal signals and back off with a short write instead.
+
+As the iomap_apply delegates all the work down to the actor we have to
+hook into those.  All callers that work with the page cache are calling
+iomap_write_begin so we will check for signals there.  dax_iomap_actor
+has to handle the situation explicitly because it copies data to the
+userspace directly.  Other callers like iomap_page_mkwrite work on a
+single page or iomap_fiemap_actor do not allocate memory based on the
+given len.
+
+Fixes: 68a9f5e7007c ("xfs: implement iomap based buffered write path")
+Link: http://lkml.kernel.org/r/20170201092706.9966-2-mhocko@kernel.org
+Signed-off-by: Michal Hocko <mhocko@suse.com>
+Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+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>
+
+---
+ fs/dax.c   |    5 +++++
+ fs/iomap.c |    3 +++
+ 2 files changed, 8 insertions(+)
+
+--- a/fs/dax.c
++++ b/fs/dax.c
+@@ -1270,6 +1270,11 @@ iomap_dax_actor(struct inode *inode, lof
+               struct blk_dax_ctl dax = { 0 };
+               ssize_t map_len;
++              if (fatal_signal_pending(current)) {
++                      ret = -EINTR;
++                      break;
++              }
++
+               dax.sector = iomap->blkno +
+                       (((pos & PAGE_MASK) - iomap->offset) >> 9);
+               dax.size = (length + offset + PAGE_SIZE - 1) & PAGE_MASK;
+--- a/fs/iomap.c
++++ b/fs/iomap.c
+@@ -113,6 +113,9 @@ iomap_write_begin(struct inode *inode, l
+       BUG_ON(pos + len > iomap->offset + iomap->length);
++      if (fatal_signal_pending(current))
++              return -EINTR;
++
+       page = grab_cache_page_write_begin(inode->i_mapping, index, flags);
+       if (!page)
+               return -ENOMEM;
index ebbc630ccf9220aa1a712b96a30bfcacc7c39ee7..31f9525b6c39206e1985c7114b445d965db42280 100644 (file)
@@ -61,5 +61,5 @@ iio-dht11-use-usleep_range-instead-of-msleep-for-start-signal.patch
 iio-health-max30100-fixed-parenthesis-around-fifo-count-check.patch
 irqdomain-avoid-activating-interrupts-more-than-once.patch
 x86-irq-make-irq-activate-operations-symmetric.patch
-firmware-fix-null-pointer-dereference-in-__fw_load_abort.patch
 iw_cxgb4-set-correct-fetchburstmax-for-qps.patch
+fs-break-out-of-iomap_file_buffered_write-on-fatal-signals.patch