]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 1 Mar 2021 16:06:24 +0000 (17:06 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 1 Mar 2021 16:06:24 +0000 (17:06 +0100)
added patches:
dm-era-update-in-core-bitset-after-committing-the-metadata.patch
net-qrtr-fix-memory-leak-in-qrtr_tun_open.patch

queue-5.4/dm-era-update-in-core-bitset-after-committing-the-metadata.patch [new file with mode: 0644]
queue-5.4/net-qrtr-fix-memory-leak-in-qrtr_tun_open.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/dm-era-update-in-core-bitset-after-committing-the-metadata.patch b/queue-5.4/dm-era-update-in-core-bitset-after-committing-the-metadata.patch
new file mode 100644 (file)
index 0000000..bfb31e9
--- /dev/null
@@ -0,0 +1,118 @@
+From 2099b145d77c1d53f5711f029c37cc537897cee6 Mon Sep 17 00:00:00 2001
+From: Nikos Tsironis <ntsironis@arrikto.com>
+Date: Fri, 22 Jan 2021 17:19:31 +0200
+Subject: dm era: Update in-core bitset after committing the metadata
+
+From: Nikos Tsironis <ntsironis@arrikto.com>
+
+commit 2099b145d77c1d53f5711f029c37cc537897cee6 upstream.
+
+In case of a system crash, dm-era might fail to mark blocks as written
+in its metadata, although the corresponding writes to these blocks were
+passed down to the origin device and completed successfully.
+
+Consider the following sequence of events:
+
+1. We write to a block that has not been yet written in the current era
+2. era_map() checks the in-core bitmap for the current era and sees
+   that the block is not marked as written.
+3. The write is deferred for submission after the metadata have been
+   updated and committed.
+4. The worker thread processes the deferred write
+   (process_deferred_bios()) and marks the block as written in the
+   in-core bitmap, **before** committing the metadata.
+5. The worker thread starts committing the metadata.
+6. We do more writes that map to the same block as the write of step (1)
+7. era_map() checks the in-core bitmap and sees that the block is marked
+   as written, **although the metadata have not been committed yet**.
+8. These writes are passed down to the origin device immediately and the
+   device reports them as completed.
+9. The system crashes, e.g., power failure, before the commit from step
+   (5) finishes.
+
+When the system recovers and we query the dm-era target for the list of
+written blocks it doesn't report the aforementioned block as written,
+although the writes of step (6) completed successfully.
+
+The issue is that era_map() decides whether to defer or not a write
+based on non committed information. The root cause of the bug is that we
+update the in-core bitmap, **before** committing the metadata.
+
+Fix this by updating the in-core bitmap **after** successfully
+committing the metadata.
+
+Fixes: eec40579d84873 ("dm: add era target")
+Cc: stable@vger.kernel.org # v3.15+
+Signed-off-by: Nikos Tsironis <ntsironis@arrikto.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/md/dm-era-target.c |   25 +++++++++++++++++++------
+ 1 file changed, 19 insertions(+), 6 deletions(-)
+
+--- a/drivers/md/dm-era-target.c
++++ b/drivers/md/dm-era-target.c
+@@ -135,7 +135,7 @@ static int writeset_test_and_set(struct
+ {
+       int r;
+-      if (!test_and_set_bit(block, ws->bits)) {
++      if (!test_bit(block, ws->bits)) {
+               r = dm_bitset_set_bit(info, ws->md.root, block, &ws->md.root);
+               if (r) {
+                       /* FIXME: fail mode */
+@@ -1241,8 +1241,10 @@ static void process_deferred_bios(struct
+       int r;
+       struct bio_list deferred_bios, marked_bios;
+       struct bio *bio;
++      struct blk_plug plug;
+       bool commit_needed = false;
+       bool failed = false;
++      struct writeset *ws = era->md->current_writeset;
+       bio_list_init(&deferred_bios);
+       bio_list_init(&marked_bios);
+@@ -1252,9 +1254,11 @@ static void process_deferred_bios(struct
+       bio_list_init(&era->deferred_bios);
+       spin_unlock(&era->deferred_lock);
++      if (bio_list_empty(&deferred_bios))
++              return;
++
+       while ((bio = bio_list_pop(&deferred_bios))) {
+-              r = writeset_test_and_set(&era->md->bitset_info,
+-                                        era->md->current_writeset,
++              r = writeset_test_and_set(&era->md->bitset_info, ws,
+                                         get_block(era, bio));
+               if (r < 0) {
+                       /*
+@@ -1262,7 +1266,6 @@ static void process_deferred_bios(struct
+                        * FIXME: finish.
+                        */
+                       failed = true;
+-
+               } else if (r == 0)
+                       commit_needed = true;
+@@ -1278,9 +1281,19 @@ static void process_deferred_bios(struct
+       if (failed)
+               while ((bio = bio_list_pop(&marked_bios)))
+                       bio_io_error(bio);
+-      else
+-              while ((bio = bio_list_pop(&marked_bios)))
++      else {
++              blk_start_plug(&plug);
++              while ((bio = bio_list_pop(&marked_bios))) {
++                      /*
++                       * Only update the in-core writeset if the on-disk one
++                       * was updated too.
++                       */
++                      if (commit_needed)
++                              set_bit(get_block(era, bio), ws->bits);
+                       generic_make_request(bio);
++              }
++              blk_finish_plug(&plug);
++      }
+ }
+ static void process_rpc_calls(struct era *era)
diff --git a/queue-5.4/net-qrtr-fix-memory-leak-in-qrtr_tun_open.patch b/queue-5.4/net-qrtr-fix-memory-leak-in-qrtr_tun_open.patch
new file mode 100644 (file)
index 0000000..5b6018f
--- /dev/null
@@ -0,0 +1,75 @@
+From fc0494ead6398609c49afa37bc949b61c5c16b91 Mon Sep 17 00:00:00 2001
+From: Takeshi Misawa <jeliantsurux@gmail.com>
+Date: Mon, 22 Feb 2021 08:44:27 +0900
+Subject: net: qrtr: Fix memory leak in qrtr_tun_open
+
+From: Takeshi Misawa <jeliantsurux@gmail.com>
+
+commit fc0494ead6398609c49afa37bc949b61c5c16b91 upstream.
+
+If qrtr_endpoint_register() failed, tun is leaked.
+Fix this, by freeing tun in error path.
+
+syzbot report:
+BUG: memory leak
+unreferenced object 0xffff88811848d680 (size 64):
+  comm "syz-executor684", pid 10171, jiffies 4294951561 (age 26.070s)
+  hex dump (first 32 bytes):
+    80 dd 0a 84 ff ff ff ff 00 00 00 00 00 00 00 00  ................
+    90 d6 48 18 81 88 ff ff 90 d6 48 18 81 88 ff ff  ..H.......H.....
+  backtrace:
+    [<0000000018992a50>] kmalloc include/linux/slab.h:552 [inline]
+    [<0000000018992a50>] kzalloc include/linux/slab.h:682 [inline]
+    [<0000000018992a50>] qrtr_tun_open+0x22/0x90 net/qrtr/tun.c:35
+    [<0000000003a453ef>] misc_open+0x19c/0x1e0 drivers/char/misc.c:141
+    [<00000000dec38ac8>] chrdev_open+0x10d/0x340 fs/char_dev.c:414
+    [<0000000079094996>] do_dentry_open+0x1e6/0x620 fs/open.c:817
+    [<000000004096d290>] do_open fs/namei.c:3252 [inline]
+    [<000000004096d290>] path_openat+0x74a/0x1b00 fs/namei.c:3369
+    [<00000000b8e64241>] do_filp_open+0xa0/0x190 fs/namei.c:3396
+    [<00000000a3299422>] do_sys_openat2+0xed/0x230 fs/open.c:1172
+    [<000000002c1bdcef>] do_sys_open fs/open.c:1188 [inline]
+    [<000000002c1bdcef>] __do_sys_openat fs/open.c:1204 [inline]
+    [<000000002c1bdcef>] __se_sys_openat fs/open.c:1199 [inline]
+    [<000000002c1bdcef>] __x64_sys_openat+0x7f/0xe0 fs/open.c:1199
+    [<00000000f3a5728f>] do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
+    [<000000004b38b7ec>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+Fixes: 28fb4e59a47d ("net: qrtr: Expose tunneling endpoint to user space")
+Reported-by: syzbot+5d6e4af21385f5cfc56a@syzkaller.appspotmail.com
+Signed-off-by: Takeshi Misawa <jeliantsurux@gmail.com>
+Link: https://lore.kernel.org/r/20210221234427.GA2140@DESKTOP
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/qrtr/tun.c |   12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/net/qrtr/tun.c
++++ b/net/qrtr/tun.c
+@@ -31,6 +31,7 @@ static int qrtr_tun_send(struct qrtr_end
+ static int qrtr_tun_open(struct inode *inode, struct file *filp)
+ {
+       struct qrtr_tun *tun;
++      int ret;
+       tun = kzalloc(sizeof(*tun), GFP_KERNEL);
+       if (!tun)
+@@ -43,7 +44,16 @@ static int qrtr_tun_open(struct inode *i
+       filp->private_data = tun;
+-      return qrtr_endpoint_register(&tun->ep, QRTR_EP_NID_AUTO);
++      ret = qrtr_endpoint_register(&tun->ep, QRTR_EP_NID_AUTO);
++      if (ret)
++              goto out;
++
++      return 0;
++
++out:
++      filp->private_data = NULL;
++      kfree(tun);
++      return ret;
+ }
+ static ssize_t qrtr_tun_read_iter(struct kiocb *iocb, struct iov_iter *to)
index 4491618a1b6588776d7cbc25e38fa3895c0cc3d7..458fc278eb21b349a2b3810d36959e60a19f9b27 100644 (file)
@@ -336,3 +336,5 @@ ipv6-icmp6-avoid-indirect-call-for-icmpv6_send.patch
 ipv6-silence-compilation-warning-for-non-ipv6-builds.patch
 net-icmp-pass-zeroed-opts-from-icmp-v6-_ndo_send-before-sending.patch
 net-sched-fix-police-ext-initialization.patch
+dm-era-update-in-core-bitset-after-committing-the-metadata.patch
+net-qrtr-fix-memory-leak-in-qrtr_tun_open.patch