--- /dev/null
+From 5c02406428d5219c367c5f53457698c58bc5f917 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Wed, 20 Jan 2021 13:59:11 -0500
+Subject: dm integrity: conditionally disable "recalculate" feature
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 5c02406428d5219c367c5f53457698c58bc5f917 upstream.
+
+Otherwise a malicious user could (ab)use the "recalculate" feature
+that makes dm-integrity calculate the checksums in the background
+while the device is already usable. When the system restarts before all
+checksums have been calculated, the calculation continues where it was
+interrupted even if the recalculate feature is not requested the next
+time the dm device is set up.
+
+Disable recalculating if we use internal_hash or journal_hash with a
+key (e.g. HMAC) and we don't have the "legacy_recalculate" flag.
+
+This may break activation of a volume, created by an older kernel,
+that is not yet fully recalculated -- if this happens, the user should
+add the "legacy_recalculate" flag to constructor parameters.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Reported-by: Daniel Glockner <dg@emlix.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ Documentation/device-mapper/dm-integrity.txt | 7 +++++++
+ drivers/md/dm-integrity.c | 24 +++++++++++++++++++++++-
+ 2 files changed, 30 insertions(+), 1 deletion(-)
+
+--- a/Documentation/device-mapper/dm-integrity.txt
++++ b/Documentation/device-mapper/dm-integrity.txt
+@@ -146,6 +146,13 @@ block_size:number
+ Supported values are 512, 1024, 2048 and 4096 bytes. If not
+ specified the default block size is 512 bytes.
+
++legacy_recalculate
++ Allow recalculating of volumes with HMAC keys. This is disabled by
++ default for security reasons - an attacker could modify the volume,
++ set recalc_sector to zero, and the kernel would not detect the
++ modification.
++
++
+ The journal mode (D/J), buffer_sectors, journal_watermark, commit_time can
+ be changed when reloading the target (load an inactive table and swap the
+ tables with suspend and resume). The other arguments should not be changed
+--- a/drivers/md/dm-integrity.c
++++ b/drivers/md/dm-integrity.c
+@@ -240,6 +240,7 @@ struct dm_integrity_c {
+
+ bool journal_uptodate;
+ bool just_formatted;
++ bool legacy_recalculate;
+
+ struct alg_spec internal_hash_alg;
+ struct alg_spec journal_crypt_alg;
+@@ -345,6 +346,14 @@ static int dm_integrity_failed(struct dm
+ return READ_ONCE(ic->failed);
+ }
+
++static bool dm_integrity_disable_recalculate(struct dm_integrity_c *ic)
++{
++ if ((ic->internal_hash_alg.key || ic->journal_mac_alg.key) &&
++ !ic->legacy_recalculate)
++ return true;
++ return false;
++}
++
+ static commit_id_t dm_integrity_commit_id(struct dm_integrity_c *ic, unsigned i,
+ unsigned j, unsigned char seq)
+ {
+@@ -2503,6 +2512,7 @@ static void dm_integrity_status(struct d
+ arg_count += !!ic->internal_hash_alg.alg_string;
+ arg_count += !!ic->journal_crypt_alg.alg_string;
+ arg_count += !!ic->journal_mac_alg.alg_string;
++ arg_count += ic->legacy_recalculate;
+ DMEMIT("%s %llu %u %c %u", ic->dev->name, (unsigned long long)ic->start,
+ ic->tag_size, ic->mode, arg_count);
+ if (ic->meta_dev)
+@@ -2516,6 +2526,8 @@ static void dm_integrity_status(struct d
+ DMEMIT(" buffer_sectors:%u", 1U << ic->log2_buffer_sectors);
+ DMEMIT(" journal_watermark:%u", (unsigned)watermark_percentage);
+ DMEMIT(" commit_time:%u", ic->autocommit_msec);
++ if (ic->legacy_recalculate)
++ DMEMIT(" legacy_recalculate");
+
+ #define EMIT_ALG(a, n) \
+ do { \
+@@ -3118,7 +3130,7 @@ static int dm_integrity_ctr(struct dm_ta
+ unsigned extra_args;
+ struct dm_arg_set as;
+ static const struct dm_arg _args[] = {
+- {0, 15, "Invalid number of feature args"},
++ {0, 12, "Invalid number of feature args"},
+ };
+ unsigned journal_sectors, interleave_sectors, buffer_sectors, journal_watermark, sync_msec;
+ bool recalculate;
+@@ -3248,6 +3260,8 @@ static int dm_integrity_ctr(struct dm_ta
+ goto bad;
+ } else if (!strcmp(opt_string, "recalculate")) {
+ recalculate = true;
++ } else if (!strcmp(opt_string, "legacy_recalculate")) {
++ ic->legacy_recalculate = true;
+ } else {
+ r = -EINVAL;
+ ti->error = "Invalid argument";
+@@ -3523,6 +3537,14 @@ try_smaller_buffer:
+ }
+ }
+
++ if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING) &&
++ le64_to_cpu(ic->sb->recalc_sector) < ic->provided_data_sectors &&
++ dm_integrity_disable_recalculate(ic)) {
++ ti->error = "Recalculating with HMAC is disabled for security reasons - if you really need it, use the argument \"legacy_recalculate\"";
++ r = -EOPNOTSUPP;
++ goto bad;
++ }
++
+ ic->bufio = dm_bufio_client_create(ic->meta_dev ? ic->meta_dev->bdev : ic->dev->bdev,
+ 1U << (SECTOR_SHIFT + ic->log2_buffer_sectors), 1, 0, NULL, NULL);
+ if (IS_ERR(ic->bufio)) {
--- /dev/null
+From foo@baz Fri Jan 29 11:41:04 AM CET 2021
+From: Eric Biggers <ebiggers@kernel.org>
+Date: Mon, 25 Jan 2021 12:05:09 -0800
+Subject: fs: fix lazytime expiration handling in __writeback_single_inode()
+To: stable@vger.kernel.org
+Cc: linux-xfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, Jan Kara <jack@suse.cz>, Christoph Hellwig <hch@lst.de>
+Message-ID: <20210125200509.261295-3-ebiggers@kernel.org>
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit 1e249cb5b7fc09ff216aa5a12f6c302e434e88f9 upstream.
+
+When lazytime is enabled and an inode is being written due to its
+in-memory updated timestamps having expired, either due to a sync() or
+syncfs() system call or due to dirtytime_expire_interval having elapsed,
+the VFS needs to inform the filesystem so that the filesystem can copy
+the inode's timestamps out to the on-disk data structures.
+
+This is done by __writeback_single_inode() calling
+mark_inode_dirty_sync(), which then calls ->dirty_inode(I_DIRTY_SYNC).
+
+However, this occurs after __writeback_single_inode() has already
+cleared the dirty flags from ->i_state. This causes two bugs:
+
+- mark_inode_dirty_sync() redirties the inode, causing it to remain
+ dirty. This wastefully causes the inode to be written twice. But
+ more importantly, it breaks cases where sync_filesystem() is expected
+ to clean dirty inodes. This includes the FS_IOC_REMOVE_ENCRYPTION_KEY
+ ioctl (as reported at
+ https://lore.kernel.org/r/20200306004555.GB225345@gmail.com), as well
+ as possibly filesystem freezing (freeze_super()).
+
+- Since ->i_state doesn't contain I_DIRTY_TIME when ->dirty_inode() is
+ called from __writeback_single_inode() for lazytime expiration,
+ xfs_fs_dirty_inode() ignores the notification. (XFS only cares about
+ lazytime expirations, and it assumes that i_state will contain
+ I_DIRTY_TIME during those.) Therefore, lazy timestamps aren't
+ persisted by sync(), syncfs(), or dirtytime_expire_interval on XFS.
+
+Fix this by moving the call to mark_inode_dirty_sync() to earlier in
+__writeback_single_inode(), before the dirty flags are cleared from
+i_state. This makes filesystems be properly notified of the timestamp
+expiration, and it avoids incorrectly redirtying the inode.
+
+This fixes xfstest generic/580 (which tests
+FS_IOC_REMOVE_ENCRYPTION_KEY) when run on ext4 or f2fs with lazytime
+enabled. It also fixes the new lazytime xfstest I've proposed, which
+reproduces the above-mentioned XFS bug
+(https://lore.kernel.org/r/20210105005818.92978-1-ebiggers@kernel.org).
+
+Alternatively, we could call ->dirty_inode(I_DIRTY_SYNC) directly. But
+due to the introduction of I_SYNC_QUEUED, mark_inode_dirty_sync() is the
+right thing to do because mark_inode_dirty_sync() now knows not to move
+the inode to a writeback list if it is currently queued for sync.
+
+Fixes: 0ae45f63d4ef ("vfs: add support for a lazytime mount option")
+Cc: stable@vger.kernel.org
+Depends-on: 5afced3bf281 ("writeback: Avoid skipping inode writeback")
+Link: https://lore.kernel.org/r/20210112190253.64307-2-ebiggers@kernel.org
+Suggested-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/fs-writeback.c | 24 +++++++++++++-----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -1393,21 +1393,25 @@ __writeback_single_inode(struct inode *i
+ }
+
+ /*
+- * Some filesystems may redirty the inode during the writeback
+- * due to delalloc, clear dirty metadata flags right before
+- * write_inode()
++ * If the inode has dirty timestamps and we need to write them, call
++ * mark_inode_dirty_sync() to notify the filesystem about it and to
++ * change I_DIRTY_TIME into I_DIRTY_SYNC.
+ */
+- spin_lock(&inode->i_lock);
+-
+- dirty = inode->i_state & I_DIRTY;
+ if ((inode->i_state & I_DIRTY_TIME) &&
+- ((dirty & I_DIRTY_INODE) ||
+- wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
++ (wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
+ time_after(jiffies, inode->dirtied_time_when +
+ dirtytime_expire_interval * HZ))) {
+- dirty |= I_DIRTY_TIME;
+ trace_writeback_lazytime(inode);
++ mark_inode_dirty_sync(inode);
+ }
++
++ /*
++ * Some filesystems may redirty the inode during the writeback
++ * due to delalloc, clear dirty metadata flags right before
++ * write_inode()
++ */
++ spin_lock(&inode->i_lock);
++ dirty = inode->i_state & I_DIRTY;
+ inode->i_state &= ~dirty;
+
+ /*
+@@ -1428,8 +1432,6 @@ __writeback_single_inode(struct inode *i
+
+ spin_unlock(&inode->i_lock);
+
+- if (dirty & I_DIRTY_TIME)
+- mark_inode_dirty_sync(inode);
+ /* Don't write the inode if only I_DIRTY_PAGES was set */
+ if (dirty & ~I_DIRTY_PAGES) {
+ int err = write_inode(inode, wbc);
futex_Handle_faults_correctly_for_PI_futexes.patch
hid-wacom-correct-null-dereference-on-aes-pen-proximity.patch
tracing-fix-race-in-trace_open-and-buffer-resize-call.patch
+tools-factor-hostcc-hostld-hostar-definitions.patch
+dm-integrity-conditionally-disable-recalculate-feature.patch
+writeback-drop-i_dirty_time_expire.patch
+fs-fix-lazytime-expiration-handling-in-__writeback_single_inode.patch
--- /dev/null
+From c8a950d0d3b926a02c7b2e713850d38217cec3d1 Mon Sep 17 00:00:00 2001
+From: Jean-Philippe Brucker <jean-philippe@linaro.org>
+Date: Tue, 10 Nov 2020 17:43:05 +0100
+Subject: tools: Factor HOSTCC, HOSTLD, HOSTAR definitions
+
+From: Jean-Philippe Brucker <jean-philippe@linaro.org>
+
+commit c8a950d0d3b926a02c7b2e713850d38217cec3d1 upstream.
+
+Several Makefiles in tools/ need to define the host toolchain variables.
+Move their definition to tools/scripts/Makefile.include
+
+Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Acked-by: Jiri Olsa <jolsa@redhat.com>
+Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Link: https://lore.kernel.org/bpf/20201110164310.2600671-2-jean-philippe@linaro.org
+Cc: Alistair Delva <adelva@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/build/Makefile | 4 ----
+ tools/objtool/Makefile | 9 ---------
+ tools/perf/Makefile.perf | 4 ----
+ tools/power/acpi/Makefile.config | 1 -
+ tools/scripts/Makefile.include | 10 ++++++++++
+ 5 files changed, 10 insertions(+), 18 deletions(-)
+
+--- a/tools/build/Makefile
++++ b/tools/build/Makefile
+@@ -15,10 +15,6 @@ endef
+ $(call allow-override,CC,$(CROSS_COMPILE)gcc)
+ $(call allow-override,LD,$(CROSS_COMPILE)ld)
+
+-HOSTCC ?= gcc
+-HOSTLD ?= ld
+-HOSTAR ?= ar
+-
+ export HOSTCC HOSTLD HOSTAR
+
+ ifeq ($(V),1)
+--- a/tools/objtool/Makefile
++++ b/tools/objtool/Makefile
+@@ -7,15 +7,6 @@ ARCH := x86
+ endif
+
+ # always use the host compiler
+-ifneq ($(LLVM),)
+-HOSTAR ?= llvm-ar
+-HOSTCC ?= clang
+-HOSTLD ?= ld.lld
+-else
+-HOSTAR ?= ar
+-HOSTCC ?= gcc
+-HOSTLD ?= ld
+-endif
+ AR = $(HOSTAR)
+ CC = $(HOSTCC)
+ LD = $(HOSTLD)
+--- a/tools/perf/Makefile.perf
++++ b/tools/perf/Makefile.perf
+@@ -148,10 +148,6 @@ endef
+
+ LD += $(EXTRA_LDFLAGS)
+
+-HOSTCC ?= gcc
+-HOSTLD ?= ld
+-HOSTAR ?= ar
+-
+ PKG_CONFIG = $(CROSS_COMPILE)pkg-config
+ LLVM_CONFIG ?= llvm-config
+
+--- a/tools/power/acpi/Makefile.config
++++ b/tools/power/acpi/Makefile.config
+@@ -57,7 +57,6 @@ INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+ CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc-
+ CROSS_COMPILE ?= $(CROSS)
+ LD = $(CC)
+-HOSTCC = gcc
+
+ # check if compiler option is supported
+ cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -x c /dev/null > /dev/null 2>&1; then echo "$(1)"; fi;}
+--- a/tools/scripts/Makefile.include
++++ b/tools/scripts/Makefile.include
+@@ -60,6 +60,16 @@ $(call allow-override,LD,$(CROSS_COMPILE
+ $(call allow-override,CXX,$(CROSS_COMPILE)g++)
+ $(call allow-override,STRIP,$(CROSS_COMPILE)strip)
+
++ifneq ($(LLVM),)
++HOSTAR ?= llvm-ar
++HOSTCC ?= clang
++HOSTLD ?= ld.lld
++else
++HOSTAR ?= ar
++HOSTCC ?= gcc
++HOSTLD ?= ld
++endif
++
+ ifeq ($(CC_NO_CLANG), 1)
+ EXTRA_WARNINGS += -Wstrict-aliasing=3
+ endif
--- /dev/null
+From foo@baz Fri Jan 29 11:41:04 AM CET 2021
+From: Eric Biggers <ebiggers@kernel.org>
+Date: Mon, 25 Jan 2021 12:05:08 -0800
+Subject: writeback: Drop I_DIRTY_TIME_EXPIRE
+To: stable@vger.kernel.org
+Cc: linux-xfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, Jan Kara <jack@suse.cz>, Christoph Hellwig <hch@lst.de>
+Message-ID: <20210125200509.261295-2-ebiggers@kernel.org>
+
+From: Jan Kara <jack@suse.cz>
+
+commit 5fcd57505c002efc5823a7355e21f48dd02d5a51 upstream.
+
+The only use of I_DIRTY_TIME_EXPIRE is to detect in
+__writeback_single_inode() that inode got there because flush worker
+decided it's time to writeback the dirty inode time stamps (either
+because we are syncing or because of age). However we can detect this
+directly in __writeback_single_inode() and there's no need for the
+strange propagation with I_DIRTY_TIME_EXPIRE flag.
+
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/inode.c | 2 +-
+ fs/fs-writeback.c | 28 +++++++++++-----------------
+ fs/xfs/xfs_trans_inode.c | 4 ++--
+ include/linux/fs.h | 1 -
+ include/trace/events/writeback.h | 1 -
+ 5 files changed, 14 insertions(+), 22 deletions(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -5209,7 +5209,7 @@ static int other_inode_match(struct inod
+ (inode->i_state & I_DIRTY_TIME)) {
+ struct ext4_inode_info *ei = EXT4_I(inode);
+
+- inode->i_state &= ~(I_DIRTY_TIME | I_DIRTY_TIME_EXPIRED);
++ inode->i_state &= ~I_DIRTY_TIME;
+ spin_unlock(&inode->i_lock);
+
+ spin_lock(&ei->i_raw_lock);
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -1157,7 +1157,7 @@ static bool inode_dirtied_after(struct i
+ */
+ static int move_expired_inodes(struct list_head *delaying_queue,
+ struct list_head *dispatch_queue,
+- int flags, unsigned long dirtied_before)
++ unsigned long dirtied_before)
+ {
+ LIST_HEAD(tmp);
+ struct list_head *pos, *node;
+@@ -1173,8 +1173,6 @@ static int move_expired_inodes(struct li
+ list_move(&inode->i_io_list, &tmp);
+ moved++;
+ spin_lock(&inode->i_lock);
+- if (flags & EXPIRE_DIRTY_ATIME)
+- inode->i_state |= I_DIRTY_TIME_EXPIRED;
+ inode->i_state |= I_SYNC_QUEUED;
+ spin_unlock(&inode->i_lock);
+ if (sb_is_blkdev_sb(inode->i_sb))
+@@ -1222,11 +1220,11 @@ static void queue_io(struct bdi_writebac
+
+ assert_spin_locked(&wb->list_lock);
+ list_splice_init(&wb->b_more_io, &wb->b_io);
+- moved = move_expired_inodes(&wb->b_dirty, &wb->b_io, 0, dirtied_before);
++ moved = move_expired_inodes(&wb->b_dirty, &wb->b_io, dirtied_before);
+ if (!work->for_sync)
+ time_expire_jif = jiffies - dirtytime_expire_interval * HZ;
+ moved += move_expired_inodes(&wb->b_dirty_time, &wb->b_io,
+- EXPIRE_DIRTY_ATIME, time_expire_jif);
++ time_expire_jif);
+ if (moved)
+ wb_io_lists_populated(wb);
+ trace_writeback_queue_io(wb, work, dirtied_before, moved);
+@@ -1402,18 +1400,14 @@ __writeback_single_inode(struct inode *i
+ spin_lock(&inode->i_lock);
+
+ dirty = inode->i_state & I_DIRTY;
+- if (inode->i_state & I_DIRTY_TIME) {
+- if ((dirty & I_DIRTY_INODE) ||
+- wbc->sync_mode == WB_SYNC_ALL ||
+- unlikely(inode->i_state & I_DIRTY_TIME_EXPIRED) ||
+- unlikely(time_after(jiffies,
+- (inode->dirtied_time_when +
+- dirtytime_expire_interval * HZ)))) {
+- dirty |= I_DIRTY_TIME | I_DIRTY_TIME_EXPIRED;
+- trace_writeback_lazytime(inode);
+- }
+- } else
+- inode->i_state &= ~I_DIRTY_TIME_EXPIRED;
++ if ((inode->i_state & I_DIRTY_TIME) &&
++ ((dirty & I_DIRTY_INODE) ||
++ wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
++ time_after(jiffies, inode->dirtied_time_when +
++ dirtytime_expire_interval * HZ))) {
++ dirty |= I_DIRTY_TIME;
++ trace_writeback_lazytime(inode);
++ }
+ inode->i_state &= ~dirty;
+
+ /*
+--- a/fs/xfs/xfs_trans_inode.c
++++ b/fs/xfs/xfs_trans_inode.c
+@@ -99,9 +99,9 @@ xfs_trans_log_inode(
+ * to log the timestamps, or will clear already cleared fields in the
+ * worst case.
+ */
+- if (inode->i_state & (I_DIRTY_TIME | I_DIRTY_TIME_EXPIRED)) {
++ if (inode->i_state & I_DIRTY_TIME) {
+ spin_lock(&inode->i_lock);
+- inode->i_state &= ~(I_DIRTY_TIME | I_DIRTY_TIME_EXPIRED);
++ inode->i_state &= ~I_DIRTY_TIME;
+ spin_unlock(&inode->i_lock);
+ }
+
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -2071,7 +2071,6 @@ static inline void init_sync_kiocb(struc
+ #define I_DIO_WAKEUP (1 << __I_DIO_WAKEUP)
+ #define I_LINKABLE (1 << 10)
+ #define I_DIRTY_TIME (1 << 11)
+-#define I_DIRTY_TIME_EXPIRED (1 << 12)
+ #define I_WB_SWITCH (1 << 13)
+ #define I_OVL_INUSE (1 << 14)
+ #define I_CREATING (1 << 15)
+--- a/include/trace/events/writeback.h
++++ b/include/trace/events/writeback.h
+@@ -20,7 +20,6 @@
+ {I_CLEAR, "I_CLEAR"}, \
+ {I_SYNC, "I_SYNC"}, \
+ {I_DIRTY_TIME, "I_DIRTY_TIME"}, \
+- {I_DIRTY_TIME_EXPIRED, "I_DIRTY_TIME_EXPIRED"}, \
+ {I_REFERENCED, "I_REFERENCED"} \
+ )
+