diff options
| author | Benjamin Marzinski <bmarzins@redhat.com> | 2025-04-15 00:17:16 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2025-05-09 09:50:33 +0200 |
| commit | 510aea4ef0f81e8d06506c85f919b7700ccc60d8 (patch) | |
| tree | 6f533bcd810b2ced96bf3ca5fc4de72e2fccb04d /drivers/md | |
| parent | af2a88817f76237abacd29f7bf78b610b5fd76f5 (diff) | |
| download | linux-510aea4ef0f81e8d06506c85f919b7700ccc60d8.tar.gz linux-510aea4ef0f81e8d06506c85f919b7700ccc60d8.tar.bz2 linux-510aea4ef0f81e8d06506c85f919b7700ccc60d8.zip | |
dm: always update the array size in realloc_argv on success
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>
Diffstat (limited to 'drivers/md')
| -rw-r--r-- | drivers/md/dm-table.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index dbd39b9722b9..543e2c568de6 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -523,9 +523,10 @@ static char **realloc_argv(unsigned int *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); |
