FAILED: patch "[PATCH] dm cache: fix flushing uninitialized delayed_work on" failed to apply to 5.4-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.4.y
git checkout FETCH_HEAD
git cherry-pick -x 135496c208ba26fd68cdef10b64ed7a91ac9a7ff
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2024110947-footbath-census-7efa@gregkh' --subject-prefix 'PATCH 5.4.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 135496c208ba26fd68cdef10b64ed7a91ac9a7ff Mon Sep 17 00:00:00 2001
From: Ming-Hung Tsai <[email protected]>
Date: Tue, 22 Oct 2024 15:12:49 +0800
Subject: [PATCH] dm cache: fix flushing uninitialized delayed_work on
cache_ctr error
An unexpected WARN_ON from flush_work() may occur when cache creation fails, caused by destroying the uninitialized delayed_work waker in the error path of cache_create(). For example, the warning appears on the superblock checksum error.
Reproduce steps:
dmsetup create cmeta --table "0 8192 linear /dev/sdc 0" dmsetup create cdata --table "0 65536 linear /dev/sdc 8192" dmsetup create corig --table "0 524288 linear /dev/sdc 262144" dd if=/dev/urandom of=/dev/mapper/cmeta bs=4k count=1 oflag=direct dmsetup create cache --table "0 524288 cache /dev/mapper/cmeta \/dev/mapper/cdata /dev/mapper/corig 128 2 metadata2 writethrough smq 0"
Kernel logs:
(snip)
WARNING: CPU: 0 PID: 84 at kernel/workqueue.c:4178 __flush_work+0x5d4/0x890
Fix by pulling out the cancel_delayed_work_sync() from the constructor's error path. This patch doesn't affect the use-after-free fix for concurrent dm_resume and dm_destroy (commit 6a459d8edbdb ("dm cache: Fix UAF in destroy()")) as cache_dtr is not changed.
drivers/md/dm-cache-target.c +15 -9
@@ -1905,16 +1905,13 @@ static void check_migrations(struct work_struct *ws)* This function gets called on the error paths of the constructor, so we * have to cope with a partially initialised struct. */ -static void destroy (struct cache *cache) +static void __destroy (struct cache *cache) { -unsigned int i; -mempool_exit (&cache->migration_pool);if (cache->prison)dm_bio_prison_destroy_v2 (cache->prison); -cancel_delayed_work_sync (&cache->waker);if (cache->wq)destroy_workqueue (cache->wq);
@@ -1942,13 +1939,22 @@ static void destroy(struct cache *cache)if (cache->policy)dm_cache_policy_destroy (cache->policy); +bioset_exit (&cache->bs); + +kfree (cache); +} + +static void destroy (struct cache *cache) +{ +unsigned int i; + +cancel_delayed_work_sync (&cache->waker); +for (i =0 ; i < cache->nr_ctr_args ; i++)kfree (cache->ctr_args[i]);kfree (cache->ctr_args); -bioset_exit (&cache->bs); - -kfree (cache); +__destroy (cache); }static void cache_dtr (struct dm_target *ti)
@@ -2561,7 +2567,7 @@ static int cache_create(struct cache_args *ca, struct cache **result) *result = cache;return 0 ; bad: -destroy (cache); +__destroy (cache);return r; }
@@ -2612,7 +2618,7 @@ static int cache_ctr(struct dm_target *ti, unsigned int argc, char **argv) r =copy_ctr_args (cache, argc -3 , (const char **)argv +3 );if (r) { -destroy (cache); +__destroy (cache); goto out; }