]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 4.4
authorSasha Levin <sashal@kernel.org>
Fri, 19 Jun 2020 04:11:10 +0000 (00:11 -0400)
committerSasha Levin <sashal@kernel.org>
Fri, 19 Jun 2020 04:11:10 +0000 (00:11 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.4/btrfs-fix-error-handling-when-submitting-direct-i-o-.patch [new file with mode: 0644]
queue-4.4/btrfs-fix-unreplayable-log-after-snapshot-delete-par.patch [new file with mode: 0644]
queue-4.4/btrfs-send-emit-file-capabilities-after-chown.patch [new file with mode: 0644]
queue-4.4/ima-directly-assign-the-ima_default_policy-pointer-t.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/btrfs-fix-error-handling-when-submitting-direct-i-o-.patch b/queue-4.4/btrfs-fix-error-handling-when-submitting-direct-i-o-.patch
new file mode 100644 (file)
index 0000000..dd34490
--- /dev/null
@@ -0,0 +1,67 @@
+From 2da76ef216300a5053ff6716c559751561406db1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Apr 2020 14:46:12 -0700
+Subject: btrfs: fix error handling when submitting direct I/O bio
+
+From: Omar Sandoval <osandov@fb.com>
+
+[ Upstream commit 6d3113a193e3385c72240096fe397618ecab6e43 ]
+
+In btrfs_submit_direct_hook(), if a direct I/O write doesn't span a RAID
+stripe or chunk, we submit orig_bio without cloning it. In this case, we
+don't increment pending_bios. Then, if btrfs_submit_dio_bio() fails, we
+decrement pending_bios to -1, and we never complete orig_bio. Fix it by
+initializing pending_bios to 1 instead of incrementing later.
+
+Fixing this exposes another bug: we put orig_bio prematurely and then
+put it again from end_io. Fix it by not putting orig_bio.
+
+After this change, pending_bios is really more of a reference count, but
+I'll leave that cleanup separate to keep the fix small.
+
+Fixes: e65e15355429 ("btrfs: fix panic caused by direct IO")
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Nikolay Borisov <nborisov@suse.com>
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Omar Sandoval <osandov@fb.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/inode.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index 548e9cd1a337..972475eeb2dd 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -8294,7 +8294,6 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
+       bio->bi_private = dip;
+       bio->bi_end_io = btrfs_end_dio_bio;
+       btrfs_io_bio(bio)->logical = file_offset;
+-      atomic_inc(&dip->pending_bios);
+       while (bvec <= (orig_bio->bi_io_vec + orig_bio->bi_vcnt - 1)) {
+               if (map_length < submit_len + bvec->bv_len ||
+@@ -8351,7 +8350,8 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
+       if (!ret)
+               return 0;
+-      bio_put(bio);
++      if (bio != orig_bio)
++              bio_put(bio);
+ out_err:
+       dip->errors = 1;
+       /*
+@@ -8398,7 +8398,7 @@ static void btrfs_submit_direct(int rw, struct bio *dio_bio,
+       io_bio->bi_private = dip;
+       dip->orig_bio = io_bio;
+       dip->dio_bio = dio_bio;
+-      atomic_set(&dip->pending_bios, 0);
++      atomic_set(&dip->pending_bios, 1);
+       btrfs_bio = btrfs_io_bio(io_bio);
+       btrfs_bio->logical = file_offset;
+-- 
+2.25.1
+
diff --git a/queue-4.4/btrfs-fix-unreplayable-log-after-snapshot-delete-par.patch b/queue-4.4/btrfs-fix-unreplayable-log-after-snapshot-delete-par.patch
new file mode 100644 (file)
index 0000000..81c660e
--- /dev/null
@@ -0,0 +1,230 @@
+From a9b6dd845c5c22f7727a78bf311ae2e6bfd44231 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Feb 2016 10:42:25 +0000
+Subject: Btrfs: fix unreplayable log after snapshot delete + parent dir fsync
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 1ec9a1ae1e30c733077c0b288c4301b66b7a81f2 ]
+
+If we delete a snapshot, fsync its parent directory and crash/power fail
+before the next transaction commit, on the next mount when we attempt to
+replay the log tree of the root containing the parent directory we will
+fail and prevent the filesystem from mounting, which is solvable by wiping
+out the log trees with the btrfs-zero-log tool but very inconvenient as
+we will lose any data and metadata fsynced before the parent directory
+was fsynced.
+
+For example:
+
+  $ mkfs.btrfs -f /dev/sdc
+  $ mount /dev/sdc /mnt
+  $ mkdir /mnt/testdir
+  $ btrfs subvolume snapshot /mnt /mnt/testdir/snap
+  $ btrfs subvolume delete /mnt/testdir/snap
+  $ xfs_io -c "fsync" /mnt/testdir
+  < crash / power failure and reboot >
+  $ mount /dev/sdc /mnt
+  mount: mount(2) failed: No such file or directory
+
+And in dmesg/syslog we get the following message and trace:
+
+[192066.361162] BTRFS info (device dm-0): failed to delete reference to snap, inode 257 parent 257
+[192066.363010] ------------[ cut here ]------------
+[192066.365268] WARNING: CPU: 4 PID: 5130 at fs/btrfs/inode.c:3986 __btrfs_unlink_inode+0x17a/0x354 [btrfs]()
+[192066.367250] BTRFS: Transaction aborted (error -2)
+[192066.368401] Modules linked in: btrfs dm_flakey dm_mod ppdev sha256_generic xor raid6_pq hmac drbg ansi_cprng aesni_intel acpi_cpufreq tpm_tis aes_x86_64 tpm ablk_helper evdev cryptd sg parport_pc i2c_piix4 psmouse lrw parport i2c_core pcspkr gf128mul processor serio_raw glue_helper button loop autofs4 ext4 crc16 mbcache jbd2 sd_mod sr_mod cdrom ata_generic virtio_scsi ata_piix libata virtio_pci virtio_ring crc32c_intel scsi_mod e1000 virtio floppy [last unloaded: btrfs]
+[192066.377154] CPU: 4 PID: 5130 Comm: mount Tainted: G        W       4.4.0-rc6-btrfs-next-20+ #1
+[192066.378875] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS by qemu-project.org 04/01/2014
+[192066.380889]  0000000000000000 ffff880143923670 ffffffff81257570 ffff8801439236b8
+[192066.382561]  ffff8801439236a8 ffffffff8104ec07 ffffffffa039dc2c 00000000fffffffe
+[192066.384191]  ffff8801ed31d000 ffff8801b9fc9c88 ffff8801086875e0 ffff880143923710
+[192066.385827] Call Trace:
+[192066.386373]  [<ffffffff81257570>] dump_stack+0x4e/0x79
+[192066.387387]  [<ffffffff8104ec07>] warn_slowpath_common+0x99/0xb2
+[192066.388429]  [<ffffffffa039dc2c>] ? __btrfs_unlink_inode+0x17a/0x354 [btrfs]
+[192066.389236]  [<ffffffff8104ec68>] warn_slowpath_fmt+0x48/0x50
+[192066.389884]  [<ffffffffa039dc2c>] __btrfs_unlink_inode+0x17a/0x354 [btrfs]
+[192066.390621]  [<ffffffff81184b55>] ? iput+0xb0/0x266
+[192066.391200]  [<ffffffffa039ea25>] btrfs_unlink_inode+0x1c/0x3d [btrfs]
+[192066.391930]  [<ffffffffa03ca623>] check_item_in_log+0x1fe/0x29b [btrfs]
+[192066.392715]  [<ffffffffa03ca827>] replay_dir_deletes+0x167/0x1cf [btrfs]
+[192066.393510]  [<ffffffffa03cccc7>] replay_one_buffer+0x417/0x570 [btrfs]
+[192066.394241]  [<ffffffffa03ca164>] walk_up_log_tree+0x10e/0x1dc [btrfs]
+[192066.394958]  [<ffffffffa03cac72>] walk_log_tree+0xa5/0x190 [btrfs]
+[192066.395628]  [<ffffffffa03ce8b8>] btrfs_recover_log_trees+0x239/0x32c [btrfs]
+[192066.396790]  [<ffffffffa03cc8b0>] ? replay_one_extent+0x50a/0x50a [btrfs]
+[192066.397891]  [<ffffffffa0394041>] open_ctree+0x1d8b/0x2167 [btrfs]
+[192066.398897]  [<ffffffffa03706e1>] btrfs_mount+0x5ef/0x729 [btrfs]
+[192066.399823]  [<ffffffff8108ad98>] ? trace_hardirqs_on+0xd/0xf
+[192066.400739]  [<ffffffff8108959b>] ? lockdep_init_map+0xb9/0x1b3
+[192066.401700]  [<ffffffff811714b9>] mount_fs+0x67/0x131
+[192066.402482]  [<ffffffff81188560>] vfs_kern_mount+0x6c/0xde
+[192066.403930]  [<ffffffffa03702bd>] btrfs_mount+0x1cb/0x729 [btrfs]
+[192066.404831]  [<ffffffff8108ad98>] ? trace_hardirqs_on+0xd/0xf
+[192066.405726]  [<ffffffff8108959b>] ? lockdep_init_map+0xb9/0x1b3
+[192066.406621]  [<ffffffff811714b9>] mount_fs+0x67/0x131
+[192066.407401]  [<ffffffff81188560>] vfs_kern_mount+0x6c/0xde
+[192066.408247]  [<ffffffff8118ae36>] do_mount+0x893/0x9d2
+[192066.409047]  [<ffffffff8113009b>] ? strndup_user+0x3f/0x8c
+[192066.409842]  [<ffffffff8118b187>] SyS_mount+0x75/0xa1
+[192066.410621]  [<ffffffff8147e517>] entry_SYSCALL_64_fastpath+0x12/0x6b
+[192066.411572] ---[ end trace 2de42126c1e0a0f0 ]---
+[192066.412344] BTRFS: error (device dm-0) in __btrfs_unlink_inode:3986: errno=-2 No such entry
+[192066.413748] BTRFS: error (device dm-0) in btrfs_replay_log:2464: errno=-2 No such entry (Failed to recover log tree)
+[192066.415458] BTRFS error (device dm-0): cleaner transaction attach returned -30
+[192066.444613] BTRFS: open_ctree failed
+
+This happens because when we are replaying the log and processing the
+directory entry pointing to the snapshot in the subvolume tree, we treat
+its btrfs_dir_item item as having a location with a key type matching
+BTRFS_INODE_ITEM_KEY, which is wrong because the type matches
+BTRFS_ROOT_ITEM_KEY and therefore must be processed differently, as the
+object id refers to a root number and not to an inode in the root
+containing the parent directory.
+
+So fix this by triggering a transaction commit if an fsync against the
+parent directory is requested after deleting a snapshot. This is the
+simplest approach for a rare use case. Some alternative that avoids the
+transaction commit would require more code to explicitly delete the
+snapshot at log replay time (factoring out common code from ioctl.c:
+btrfs_ioctl_snap_destroy()), special care at fsync time to remove the
+log tree of the snapshot's root from the log root of the root of tree
+roots, amongst other steps.
+
+A test case for xfstests that triggers the issue follows.
+
+  seq=`basename $0`
+  seqres=$RESULT_DIR/$seq
+  echo "QA output created by $seq"
+  tmp=/tmp/$$
+  status=1     # failure is the default!
+  trap "_cleanup; exit \$status" 0 1 2 3 15
+
+  _cleanup()
+  {
+      _cleanup_flakey
+      cd /
+      rm -f $tmp.*
+  }
+
+  # get standard environment, filters and checks
+  . ./common/rc
+  . ./common/filter
+  . ./common/dmflakey
+
+  # real QA test starts here
+  _need_to_be_root
+  _supported_fs btrfs
+  _supported_os Linux
+  _require_scratch
+  _require_dm_target flakey
+  _require_metadata_journaling $SCRATCH_DEV
+
+  rm -f $seqres.full
+
+  _scratch_mkfs >>$seqres.full 2>&1
+  _init_flakey
+  _mount_flakey
+
+  # Create a snapshot at the root of our filesystem (mount point path), delete it,
+  # fsync the mount point path, crash and mount to replay the log. This should
+  # succeed and after the filesystem is mounted the snapshot should not be visible
+  # anymore.
+  _run_btrfs_util_prog subvolume snapshot $SCRATCH_MNT $SCRATCH_MNT/snap1
+  _run_btrfs_util_prog subvolume delete $SCRATCH_MNT/snap1
+  $XFS_IO_PROG -c "fsync" $SCRATCH_MNT
+  _flakey_drop_and_remount
+  [ -e $SCRATCH_MNT/snap1 ] && \
+      echo "Snapshot snap1 still exists after log replay"
+
+  # Similar scenario as above, but this time the snapshot is created inside a
+  # directory and not directly under the root (mount point path).
+  mkdir $SCRATCH_MNT/testdir
+  _run_btrfs_util_prog subvolume snapshot $SCRATCH_MNT $SCRATCH_MNT/testdir/snap2
+  _run_btrfs_util_prog subvolume delete $SCRATCH_MNT/testdir/snap2
+  $XFS_IO_PROG -c "fsync" $SCRATCH_MNT/testdir
+  _flakey_drop_and_remount
+  [ -e $SCRATCH_MNT/testdir/snap2 ] && \
+      echo "Snapshot snap2 still exists after log replay"
+
+  _unmount_flakey
+
+  echo "Silence is golden"
+  status=0
+  exit
+
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Tested-by: Liu Bo <bo.li.liu@oracle.com>
+Reviewed-by: Liu Bo <bo.li.liu@oracle.com>
+Signed-off-by: Chris Mason <clm@fb.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/ioctl.c    |  3 +++
+ fs/btrfs/tree-log.c | 15 +++++++++++++++
+ fs/btrfs/tree-log.h |  2 ++
+ 3 files changed, 20 insertions(+)
+
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index 119b1c5c279b..245a50f490f6 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -59,6 +59,7 @@
+ #include "props.h"
+ #include "sysfs.h"
+ #include "qgroup.h"
++#include "tree-log.h"
+ #ifdef CONFIG_64BIT
+ /* If we have a 32-bit userspace and 64-bit kernel, then the UAPI
+@@ -2540,6 +2541,8 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
+ out_end_trans:
+       trans->block_rsv = NULL;
+       trans->bytes_reserved = 0;
++      if (!err)
++              btrfs_record_snapshot_destroy(trans, dir);
+       ret = btrfs_end_transaction(trans, root);
+       if (ret && !err)
+               err = ret;
+diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
+index 4320f346b0b9..3779a660988a 100644
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -5694,6 +5694,21 @@ void btrfs_record_unlink_dir(struct btrfs_trans_handle *trans,
+       BTRFS_I(dir)->last_unlink_trans = trans->transid;
+ }
++/*
++ * Make sure that if someone attempts to fsync the parent directory of a deleted
++ * snapshot, it ends up triggering a transaction commit. This is to guarantee
++ * that after replaying the log tree of the parent directory's root we will not
++ * see the snapshot anymore and at log replay time we will not see any log tree
++ * corresponding to the deleted snapshot's root, which could lead to replaying
++ * it after replaying the log tree of the parent directory (which would replay
++ * the snapshot delete operation).
++ */
++void btrfs_record_snapshot_destroy(struct btrfs_trans_handle *trans,
++                                 struct inode *dir)
++{
++      BTRFS_I(dir)->last_unlink_trans = trans->transid;
++}
++
+ /*
+  * Call this after adding a new name for a file and it will properly
+  * update the log to reflect the new name.
+diff --git a/fs/btrfs/tree-log.h b/fs/btrfs/tree-log.h
+index 6916a781ea02..a9f1b75d080d 100644
+--- a/fs/btrfs/tree-log.h
++++ b/fs/btrfs/tree-log.h
+@@ -79,6 +79,8 @@ int btrfs_pin_log_trans(struct btrfs_root *root);
+ void btrfs_record_unlink_dir(struct btrfs_trans_handle *trans,
+                            struct inode *dir, struct inode *inode,
+                            int for_rename);
++void btrfs_record_snapshot_destroy(struct btrfs_trans_handle *trans,
++                                 struct inode *dir);
+ int btrfs_log_new_name(struct btrfs_trans_handle *trans,
+                       struct inode *inode, struct inode *old_dir,
+                       struct dentry *parent);
+-- 
+2.25.1
+
diff --git a/queue-4.4/btrfs-send-emit-file-capabilities-after-chown.patch b/queue-4.4/btrfs-send-emit-file-capabilities-after-chown.patch
new file mode 100644 (file)
index 0000000..5f1f95b
--- /dev/null
@@ -0,0 +1,158 @@
+From 13bd0fff20689cf2671435a5770d143f0e8809d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 May 2020 23:15:07 -0300
+Subject: btrfs: send: emit file capabilities after chown
+
+From: Marcos Paulo de Souza <mpdesouza@suse.com>
+
+[ Upstream commit 89efda52e6b6930f80f5adda9c3c9edfb1397191 ]
+
+Whenever a chown is executed, all capabilities of the file being touched
+are lost.  When doing incremental send with a file with capabilities,
+there is a situation where the capability can be lost on the receiving
+side. The sequence of actions bellow shows the problem:
+
+  $ mount /dev/sda fs1
+  $ mount /dev/sdb fs2
+
+  $ touch fs1/foo.bar
+  $ setcap cap_sys_nice+ep fs1/foo.bar
+  $ btrfs subvolume snapshot -r fs1 fs1/snap_init
+  $ btrfs send fs1/snap_init | btrfs receive fs2
+
+  $ chgrp adm fs1/foo.bar
+  $ setcap cap_sys_nice+ep fs1/foo.bar
+
+  $ btrfs subvolume snapshot -r fs1 fs1/snap_complete
+  $ btrfs subvolume snapshot -r fs1 fs1/snap_incremental
+
+  $ btrfs send fs1/snap_complete | btrfs receive fs2
+  $ btrfs send -p fs1/snap_init fs1/snap_incremental | btrfs receive fs2
+
+At this point, only a chown was emitted by "btrfs send" since only the
+group was changed. This makes the cap_sys_nice capability to be dropped
+from fs2/snap_incremental/foo.bar
+
+To fix that, only emit capabilities after chown is emitted. The current
+code first checks for xattrs that are new/changed, emits them, and later
+emit the chown. Now, __process_new_xattr skips capabilities, letting
+only finish_inode_if_needed to emit them, if they exist, for the inode
+being processed.
+
+This behavior was being worked around in "btrfs receive" side by caching
+the capability and only applying it after chown. Now, xattrs are only
+emmited _after_ chown, making that workaround not needed anymore.
+
+Link: https://github.com/kdave/btrfs-progs/issues/202
+CC: stable@vger.kernel.org # 4.4+
+Suggested-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/send.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 67 insertions(+)
+
+diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
+index f35884a431c1..de0ebb3b3cd3 100644
+--- a/fs/btrfs/send.c
++++ b/fs/btrfs/send.c
+@@ -34,6 +34,7 @@
+ #include "disk-io.h"
+ #include "btrfs_inode.h"
+ #include "transaction.h"
++#include "xattr.h"
+ static int g_verbose = 0;
+@@ -4194,6 +4195,10 @@ static int __process_new_xattr(int num, struct btrfs_key *di_key,
+       struct fs_path *p;
+       posix_acl_xattr_header dummy_acl;
++      /* Capabilities are emitted by finish_inode_if_needed */
++      if (!strncmp(name, XATTR_NAME_CAPS, name_len))
++              return 0;
++
+       p = fs_path_alloc();
+       if (!p)
+               return -ENOMEM;
+@@ -4733,6 +4738,64 @@ static int send_extent_data(struct send_ctx *sctx,
+       return 0;
+ }
++/*
++ * Search for a capability xattr related to sctx->cur_ino. If the capability is
++ * found, call send_set_xattr function to emit it.
++ *
++ * Return 0 if there isn't a capability, or when the capability was emitted
++ * successfully, or < 0 if an error occurred.
++ */
++static int send_capabilities(struct send_ctx *sctx)
++{
++      struct fs_path *fspath = NULL;
++      struct btrfs_path *path;
++      struct btrfs_dir_item *di;
++      struct extent_buffer *leaf;
++      unsigned long data_ptr;
++      char *buf = NULL;
++      int buf_len;
++      int ret = 0;
++
++      path = alloc_path_for_send();
++      if (!path)
++              return -ENOMEM;
++
++      di = btrfs_lookup_xattr(NULL, sctx->send_root, path, sctx->cur_ino,
++                              XATTR_NAME_CAPS, strlen(XATTR_NAME_CAPS), 0);
++      if (!di) {
++              /* There is no xattr for this inode */
++              goto out;
++      } else if (IS_ERR(di)) {
++              ret = PTR_ERR(di);
++              goto out;
++      }
++
++      leaf = path->nodes[0];
++      buf_len = btrfs_dir_data_len(leaf, di);
++
++      fspath = fs_path_alloc();
++      buf = kmalloc(buf_len, GFP_KERNEL);
++      if (!fspath || !buf) {
++              ret = -ENOMEM;
++              goto out;
++      }
++
++      ret = get_cur_path(sctx, sctx->cur_ino, sctx->cur_inode_gen, fspath);
++      if (ret < 0)
++              goto out;
++
++      data_ptr = (unsigned long)(di + 1) + btrfs_dir_name_len(leaf, di);
++      read_extent_buffer(leaf, buf, data_ptr, buf_len);
++
++      ret = send_set_xattr(sctx, fspath, XATTR_NAME_CAPS,
++                      strlen(XATTR_NAME_CAPS), buf, buf_len);
++out:
++      kfree(buf);
++      fs_path_free(fspath);
++      btrfs_free_path(path);
++      return ret;
++}
++
+ static int clone_range(struct send_ctx *sctx,
+                      struct clone_root *clone_root,
+                      const u64 disk_byte,
+@@ -5444,6 +5507,10 @@ static int finish_inode_if_needed(struct send_ctx *sctx, int at_end)
+                       goto out;
+       }
++      ret = send_capabilities(sctx);
++      if (ret < 0)
++              goto out;
++
+       /*
+        * If other directory inodes depended on our current directory
+        * inode's move/rename, now do their move/rename operations.
+-- 
+2.25.1
+
diff --git a/queue-4.4/ima-directly-assign-the-ima_default_policy-pointer-t.patch b/queue-4.4/ima-directly-assign-the-ima_default_policy-pointer-t.patch
new file mode 100644 (file)
index 0000000..a416bad
--- /dev/null
@@ -0,0 +1,66 @@
+From c6fd2018d7846a4fc7c2d2f0e1b348c7a1e804b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jun 2020 17:08:20 +0200
+Subject: ima: Directly assign the ima_default_policy pointer to ima_rules
+
+From: Roberto Sassu <roberto.sassu@huawei.com>
+
+[ Upstream commit 067a436b1b0aafa593344fddd711a755a58afb3b ]
+
+This patch prevents the following oops:
+
+[   10.771813] BUG: kernel NULL pointer dereference, address: 0000000000000
+[...]
+[   10.779790] RIP: 0010:ima_match_policy+0xf7/0xb80
+[...]
+[   10.798576] Call Trace:
+[   10.798993]  ? ima_lsm_policy_change+0x2b0/0x2b0
+[   10.799753]  ? inode_init_owner+0x1a0/0x1a0
+[   10.800484]  ? _raw_spin_lock+0x7a/0xd0
+[   10.801592]  ima_must_appraise.part.0+0xb6/0xf0
+[   10.802313]  ? ima_fix_xattr.isra.0+0xd0/0xd0
+[   10.803167]  ima_must_appraise+0x4f/0x70
+[   10.804004]  ima_post_path_mknod+0x2e/0x80
+[   10.804800]  do_mknodat+0x396/0x3c0
+
+It occurs when there is a failure during IMA initialization, and
+ima_init_policy() is not called. IMA hooks still call ima_match_policy()
+but ima_rules is NULL. This patch prevents the crash by directly assigning
+the ima_default_policy pointer to ima_rules when ima_rules is defined. This
+wouldn't alter the existing behavior, as ima_rules is always set at the end
+of ima_init_policy().
+
+Cc: stable@vger.kernel.org # 3.7.x
+Fixes: 07f6a79415d7d ("ima: add appraise action keywords and default rules")
+Reported-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/integrity/ima/ima_policy.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
+index 3997e206f82d..0ddc8cb6411b 100644
+--- a/security/integrity/ima/ima_policy.c
++++ b/security/integrity/ima/ima_policy.c
+@@ -135,7 +135,7 @@ static struct ima_rule_entry default_appraise_rules[] = {
+ static LIST_HEAD(ima_default_rules);
+ static LIST_HEAD(ima_policy_rules);
+-static struct list_head *ima_rules;
++static struct list_head *ima_rules = &ima_default_rules;
+ static DEFINE_MUTEX(ima_rules_mutex);
+@@ -412,7 +412,6 @@ void __init ima_init_policy(void)
+                             &ima_default_rules);
+       }
+-      ima_rules = &ima_default_rules;
+ }
+ /**
+-- 
+2.25.1
+
index 39a1934341edfd3ab3df7643b958920ec2ac60d6..3ee4acf69be776f0f302508c3c73106740210821 100644 (file)
@@ -75,3 +75,7 @@ spi-dw-return-any-value-retrieved-from-the-dma_trans.patch
 cpuidle-fix-three-reference-count-leaks.patch
 ima-fix-ima-digest-hash-table-key-calculation.patch
 ext4-fix-ext_max_extent-index-to-check-for-zeroed-eh_max.patch
+btrfs-fix-unreplayable-log-after-snapshot-delete-par.patch
+btrfs-send-emit-file-capabilities-after-chown.patch
+btrfs-fix-error-handling-when-submitting-direct-i-o-.patch
+ima-directly-assign-the-ima_default_policy-pointer-t.patch