]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
dm: always update the array size in realloc_argv on success
authorBenjamin Marzinski <bmarzins@redhat.com>
Tue, 15 Apr 2025 04:17:16 +0000 (00:17 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Jun 2025 12:36:51 +0000 (14:36 +0200)
commit 5a2a6c428190f945c5cbf5791f72dbea83e97f66 upstream.

realloc_argv() was only updating the array size if it was called with
old_argv already allocated. The first time it was called to create an
argv array, it would allocate the array but return the array size as
zero. dm_split_args() would think that it couldn't store any arguments
in the array and would call realloc_argv() again, causing it to
reallocate the initial slots (this time using GPF_KERNEL) and finally
return a size. Aside from being wasteful, this could cause deadlocks on
targets that need to process messages without starting new IO. Instead,
realloc_argv should always update the allocated array size on success.

Fixes: a0651926553c ("dm table: don't copy from a NULL pointer in realloc_argv()")
Cc: stable@vger.kernel.org
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/md/dm-table.c

index 31bcdcd93c7a873e4cfaad7fe488d8537a404c39..dac59ccafd75799eaf157c60b5ff9b3d3bcb315e 100644 (file)
@@ -513,9 +513,10 @@ static char **realloc_argv(unsigned *size, char **old_argv)
                gfp = GFP_NOIO;
        }
        argv = kmalloc_array(new_size, sizeof(*argv), gfp);
-       if (argv && old_argv) {
-               memcpy(argv, old_argv, *size * sizeof(*argv));
+       if (argv) {
                *size = new_size;
+               if (old_argv)
+                       memcpy(argv, old_argv, *size * sizeof(*argv));
        }
 
        kfree(old_argv);