]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 24 May 2021 12:50:22 +0000 (14:50 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 24 May 2021 12:50:22 +0000 (14:50 +0200)
added patches:
bluetooth-l2cap-fix-handling-le-modes-by-l2cap_options.patch
ext4-fix-error-handling-in-ext4_end_enable_verity.patch

queue-5.4/bluetooth-l2cap-fix-handling-le-modes-by-l2cap_options.patch [new file with mode: 0644]
queue-5.4/ext4-fix-error-handling-in-ext4_end_enable_verity.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/bluetooth-l2cap-fix-handling-le-modes-by-l2cap_options.patch b/queue-5.4/bluetooth-l2cap-fix-handling-le-modes-by-l2cap_options.patch
new file mode 100644 (file)
index 0000000..7685232
--- /dev/null
@@ -0,0 +1,66 @@
+From b86b0b150fed840c376145383ef5105116c81b0c Mon Sep 17 00:00:00 2001
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Date: Fri, 27 Mar 2020 11:32:14 -0700
+Subject: Bluetooth: L2CAP: Fix handling LE modes by L2CAP_OPTIONS
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+commit b86b0b150fed840c376145383ef5105116c81b0c upstream.
+
+L2CAP_OPTIONS shall only be used with BR/EDR modes.
+
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Zubin Mithra <zsm@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/l2cap_sock.c |   24 ++++++++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+--- a/net/bluetooth/l2cap_sock.c
++++ b/net/bluetooth/l2cap_sock.c
+@@ -426,6 +426,20 @@ static int l2cap_sock_getsockopt_old(str
+                       break;
+               }
++              /* Only BR/EDR modes are supported here */
++              switch (chan->mode) {
++              case L2CAP_MODE_BASIC:
++              case L2CAP_MODE_ERTM:
++              case L2CAP_MODE_STREAMING:
++                      break;
++              default:
++                      err = -EINVAL;
++                      break;
++              }
++
++              if (err < 0)
++                      break;
++
+               memset(&opts, 0, sizeof(opts));
+               opts.imtu     = chan->imtu;
+               opts.omtu     = chan->omtu;
+@@ -685,10 +699,8 @@ static int l2cap_sock_setsockopt_old(str
+                       break;
+               }
+-              chan->mode = opts.mode;
+-              switch (chan->mode) {
+-              case L2CAP_MODE_LE_FLOWCTL:
+-                      break;
++              /* Only BR/EDR modes are supported here */
++              switch (opts.mode) {
+               case L2CAP_MODE_BASIC:
+                       clear_bit(CONF_STATE2_DEVICE, &chan->conf_state);
+                       break;
+@@ -702,6 +714,10 @@ static int l2cap_sock_setsockopt_old(str
+                       break;
+               }
++              if (err < 0)
++                      break;
++
++              chan->mode = opts.mode;
+               chan->imtu = opts.imtu;
+               chan->omtu = opts.omtu;
+               chan->fcs  = opts.fcs;
diff --git a/queue-5.4/ext4-fix-error-handling-in-ext4_end_enable_verity.patch b/queue-5.4/ext4-fix-error-handling-in-ext4_end_enable_verity.patch
new file mode 100644 (file)
index 0000000..79fb88f
--- /dev/null
@@ -0,0 +1,148 @@
+From f053cf7aa66cd9d592b0fc967f4d887c2abff1b7 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Tue, 2 Mar 2021 12:04:19 -0800
+Subject: ext4: fix error handling in ext4_end_enable_verity()
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit f053cf7aa66cd9d592b0fc967f4d887c2abff1b7 upstream.
+
+ext4 didn't properly clean up if verity failed to be enabled on a file:
+
+- It left verity metadata (pages past EOF) in the page cache, which
+  would be exposed to userspace if the file was later extended.
+
+- It didn't truncate the verity metadata at all (either from cache or
+  from disk) if an error occurred while setting the verity bit.
+
+Fix these bugs by adding a call to truncate_inode_pages() and ensuring
+that we truncate the verity metadata (both from cache and from disk) in
+all error paths.  Also rework the code to cleanly separate the success
+path from the error paths, which makes it much easier to understand.
+
+Reported-by: Yunlei He <heyunlei@hihonor.com>
+Fixes: c93d8f885809 ("ext4: add basic fs-verity support")
+Cc: stable@vger.kernel.org # v5.4+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Link: https://lore.kernel.org/r/20210302200420.137977-2-ebiggers@kernel.org
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/verity.c |   93 +++++++++++++++++++++++++++++++++----------------------
+ 1 file changed, 57 insertions(+), 36 deletions(-)
+
+--- a/fs/ext4/verity.c
++++ b/fs/ext4/verity.c
+@@ -198,55 +198,76 @@ static int ext4_end_enable_verity(struct
+       struct inode *inode = file_inode(filp);
+       const int credits = 2; /* superblock and inode for ext4_orphan_del() */
+       handle_t *handle;
++      struct ext4_iloc iloc;
+       int err = 0;
+-      int err2;
+-      if (desc != NULL) {
+-              /* Succeeded; write the verity descriptor. */
+-              err = ext4_write_verity_descriptor(inode, desc, desc_size,
+-                                                 merkle_tree_size);
+-
+-              /* Write all pages before clearing VERITY_IN_PROGRESS. */
+-              if (!err)
+-                      err = filemap_write_and_wait(inode->i_mapping);
+-      }
++      /*
++       * If an error already occurred (which fs/verity/ signals by passing
++       * desc == NULL), then only clean-up is needed.
++       */
++      if (desc == NULL)
++              goto cleanup;
+-      /* If we failed, truncate anything we wrote past i_size. */
+-      if (desc == NULL || err)
+-              ext4_truncate(inode);
++      /* Append the verity descriptor. */
++      err = ext4_write_verity_descriptor(inode, desc, desc_size,
++                                         merkle_tree_size);
++      if (err)
++              goto cleanup;
+       /*
+-       * We must always clean up by clearing EXT4_STATE_VERITY_IN_PROGRESS and
+-       * deleting the inode from the orphan list, even if something failed.
+-       * If everything succeeded, we'll also set the verity bit in the same
+-       * transaction.
++       * Write all pages (both data and verity metadata).  Note that this must
++       * happen before clearing EXT4_STATE_VERITY_IN_PROGRESS; otherwise pages
++       * beyond i_size won't be written properly.  For crash consistency, this
++       * also must happen before the verity inode flag gets persisted.
+        */
++      err = filemap_write_and_wait(inode->i_mapping);
++      if (err)
++              goto cleanup;
+-      ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS);
++      /*
++       * Finally, set the verity inode flag and remove the inode from the
++       * orphan list (in a single transaction).
++       */
+       handle = ext4_journal_start(inode, EXT4_HT_INODE, credits);
+       if (IS_ERR(handle)) {
+-              ext4_orphan_del(NULL, inode);
+-              return PTR_ERR(handle);
++              err = PTR_ERR(handle);
++              goto cleanup;
+       }
+-      err2 = ext4_orphan_del(handle, inode);
+-      if (err2)
+-              goto out_stop;
+-
+-      if (desc != NULL && !err) {
+-              struct ext4_iloc iloc;
+-
+-              err = ext4_reserve_inode_write(handle, inode, &iloc);
+-              if (err)
+-                      goto out_stop;
+-              ext4_set_inode_flag(inode, EXT4_INODE_VERITY);
+-              ext4_set_inode_flags(inode);
+-              err = ext4_mark_iloc_dirty(handle, inode, &iloc);
+-      }
+-out_stop:
++      err = ext4_orphan_del(handle, inode);
++      if (err)
++              goto stop_and_cleanup;
++
++      err = ext4_reserve_inode_write(handle, inode, &iloc);
++      if (err)
++              goto stop_and_cleanup;
++
++      ext4_set_inode_flag(inode, EXT4_INODE_VERITY);
++      ext4_set_inode_flags(inode);
++      err = ext4_mark_iloc_dirty(handle, inode, &iloc);
++      if (err)
++              goto stop_and_cleanup;
++
+       ext4_journal_stop(handle);
+-      return err ?: err2;
++
++      ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS);
++      return 0;
++
++stop_and_cleanup:
++      ext4_journal_stop(handle);
++cleanup:
++      /*
++       * Verity failed to be enabled, so clean up by truncating any verity
++       * metadata that was written beyond i_size (both from cache and from
++       * disk), removing the inode from the orphan list (if it wasn't done
++       * already), and clearing EXT4_STATE_VERITY_IN_PROGRESS.
++       */
++      truncate_inode_pages(inode->i_mapping, inode->i_size);
++      ext4_truncate(inode);
++      ext4_orphan_del(NULL, inode);
++      ext4_clear_inode_state(inode, EXT4_STATE_VERITY_IN_PROGRESS);
++      return err;
+ }
+ static int ext4_get_verity_descriptor_location(struct inode *inode,
index 60f8920b584343b0ae9479b003d30b60b807e6cc..3b98ccff963dfdb7f1b56bb0ad397eb15ff9fc89 100644 (file)
@@ -67,3 +67,5 @@ vgacon-record-video-mode-changes-with-vt_resizex.patch
 vt-fix-character-height-handling-with-vt_resizex.patch
 tty-vt-always-invoke-vc-vc_sw-con_resize-callback.patch
 nvme-multipath-fix-double-initialization-of-ana-state.patch
+ext4-fix-error-handling-in-ext4_end_enable_verity.patch
+bluetooth-l2cap-fix-handling-le-modes-by-l2cap_options.patch