From: Sasha Levin Date: Wed, 29 Nov 2023 19:52:46 +0000 (-0500) Subject: Fixes for 4.19 X-Git-Tag: v5.15.141~15^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f087f269b398970987e57c480055ae129df5e8db;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.19 Signed-off-by: Sasha Levin --- diff --git a/queue-4.19/dm-delay-fix-a-race-between-delay_presuspend-and-del.patch b/queue-4.19/dm-delay-fix-a-race-between-delay_presuspend-and-del.patch new file mode 100644 index 00000000000..1b9d9683b39 --- /dev/null +++ b/queue-4.19/dm-delay-fix-a-race-between-delay_presuspend-and-del.patch @@ -0,0 +1,98 @@ +From 6d4ac18ce5263caf8368f49ae9dd0e171823015c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Nov 2023 13:38:43 -0500 +Subject: dm-delay: fix a race between delay_presuspend and delay_bio + +From: Mikulas Patocka + +[ Upstream commit 6fc45b6ed921dc00dfb264dc08c7d67ee63d2656 ] + +In delay_presuspend, we set the atomic variable may_delay and then stop +the timer and flush pending bios. The intention here is to prevent the +delay target from re-arming the timer again. + +However, this test is racy. Suppose that one thread goes to delay_bio, +sees that dc->may_delay is one and proceeds; now, another thread executes +delay_presuspend, it sets dc->may_delay to zero, deletes the timer and +flushes pending bios. Then, the first thread continues and adds the bio to +delayed->list despite the fact that dc->may_delay is false. + +Fix this bug by changing may_delay's type from atomic_t to bool and +only access it while holding the delayed_bios_lock mutex. Note that we +don't have to grab the mutex in delay_resume because there are no bios +in flight at this point. + +Signed-off-by: Mikulas Patocka +Cc: stable@vger.kernel.org +Signed-off-by: Mike Snitzer +Signed-off-by: Sasha Levin +--- + drivers/md/dm-delay.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c +index f496213f8b675..7c0e7c662e07f 100644 +--- a/drivers/md/dm-delay.c ++++ b/drivers/md/dm-delay.c +@@ -30,7 +30,7 @@ struct delay_c { + struct workqueue_struct *kdelayd_wq; + struct work_struct flush_expired_bios; + struct list_head delayed_bios; +- atomic_t may_delay; ++ bool may_delay; + + struct delay_class read; + struct delay_class write; +@@ -191,7 +191,7 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv) + INIT_WORK(&dc->flush_expired_bios, flush_expired_bios); + INIT_LIST_HEAD(&dc->delayed_bios); + mutex_init(&dc->timer_lock); +- atomic_set(&dc->may_delay, 1); ++ dc->may_delay = true; + dc->argc = argc; + + ret = delay_class_ctr(ti, &dc->read, argv); +@@ -245,7 +245,7 @@ static int delay_bio(struct delay_c *dc, struct delay_class *c, struct bio *bio) + struct dm_delay_info *delayed; + unsigned long expires = 0; + +- if (!c->delay || !atomic_read(&dc->may_delay)) ++ if (!c->delay) + return DM_MAPIO_REMAPPED; + + delayed = dm_per_bio_data(bio, sizeof(struct dm_delay_info)); +@@ -254,6 +254,10 @@ static int delay_bio(struct delay_c *dc, struct delay_class *c, struct bio *bio) + delayed->expires = expires = jiffies + msecs_to_jiffies(c->delay); + + mutex_lock(&delayed_bios_lock); ++ if (unlikely(!dc->may_delay)) { ++ mutex_unlock(&delayed_bios_lock); ++ return DM_MAPIO_REMAPPED; ++ } + c->ops++; + list_add_tail(&delayed->list, &dc->delayed_bios); + mutex_unlock(&delayed_bios_lock); +@@ -267,7 +271,10 @@ static void delay_presuspend(struct dm_target *ti) + { + struct delay_c *dc = ti->private; + +- atomic_set(&dc->may_delay, 0); ++ mutex_lock(&delayed_bios_lock); ++ dc->may_delay = false; ++ mutex_unlock(&delayed_bios_lock); ++ + del_timer_sync(&dc->delay_timer); + flush_bios(flush_delayed_bios(dc, 1)); + } +@@ -276,7 +283,7 @@ static void delay_resume(struct dm_target *ti) + { + struct delay_c *dc = ti->private; + +- atomic_set(&dc->may_delay, 1); ++ dc->may_delay = true; + } + + static int delay_map(struct dm_target *ti, struct bio *bio) +-- +2.42.0 + diff --git a/queue-4.19/series b/queue-4.19/series index 64a7cb71e7c..31ad6a0ba2d 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -16,3 +16,4 @@ tracing-kprobes-return-eaddrnotavail-when-func-matches-several-symbols.patch arm64-cpufeature-extract-capped-perfmon-fields.patch kvm-arm64-limit-pmu-version-to-pmuv3-for-armv8.1.patch mtd-rawnand-brcmnand-fix-ecc-chunk-calculation-for-erased-page-bitfips.patch +dm-delay-fix-a-race-between-delay_presuspend-and-del.patch