From: sashiko-bot@kernel.org
To: ghuicao@163.com
Cc: yukuai@fygo.io, linux-raid@vger.kernel.org
Subject: Re: [PATCH v2 2/3] md/raid5: fix leak and use-after-free in resize_stripes error path
Date: Thu, 27 Aug 2026 06:27:51 +0000 [thread overview]
Message-ID: <20260827062751.768881F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260827060554.77849-2-ghuicao@163.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [Critical] Concurrent lockless read of `conf->disks` in IO and error paths races with synchronous `kfree(old_disks)`.
- [High] Memory leak of `stripe_head` pages (`nsh->dev[i].page`) when Step 4 of `resize_stripes()` fails.
--
commit 42a858726c79b14d53c892c406bd10d16e4932f8
Author: Cao Guanghui <caoguanghui@kylinos.cn>
md/raid5: fix leak and use-after-free in resize_stripes error path
This commit attempts to fix a memory leak and a use-after-free issue
in the resize_stripes error path. It defers the conf->disks replacement
and performs it under mddev->lock to prevent concurrent reads in
raid5_status from seeing a freed array.
Cc: stable@vger.kernel.org
> diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
> index 4efaef622fc05..e481c48b45093 100644
> --- a/drivers/md/raid5.c
> +++ b/drivers/md/raid5.c
[ ... ]
> @@ -2685,8 +2683,20 @@ static int resize_stripes(struct r5conf *conf, int newsize)
> }
> /* critical section pass, GFP_NOIO no longer needed */
>
> - if (!err)
> + if (!err && ndisks) {
> + struct disk_info *old_disks = conf->disks;
> +
> + spin_lock_irq(&conf->mddev->lock);
> + conf->disks = ndisks;
> + spin_unlock_irq(&conf->mddev->lock);
> + kfree(old_disks);
[Severity: Critical]
This is a pre-existing issue, but the patch's attempt to fix the conf->disks
use-after-free is incomplete and leaves critical race windows open. This
kfree() is synchronous and doesn't wait for an RCU grace period.
Because check_reshape() invokes resize_stripes() before reshape_position is
updated, chunk_aligned_read is still enabled. Does this allow
raid5_read_one_chunk() to run concurrently and read the freed conf->disks
array completely locklessly?
drivers/md/raid5.c:raid5_read_one_chunk() {
...
rdev = conf->disks[dd_idx].replacement;
if (!rdev || test_bit(Faulty, &rdev->flags) ||
READ_ONCE(rdev->recovery_offset) < end_sector) {
rdev = conf->disks[dd_idx].rdev;
...
}
Additionally, raid5_calc_degraded() iterates over conf->disks holding only
rcu_read_lock(). Will this synchronous kfree() cause a use-after-free for
those RCU readers as well?
drivers/md/raid5.c:raid5_calc_degraded() {
...
struct md_rdev *rdev = READ_ONCE(conf->disks[i].rdev);
...
}
> conf->pool_size = newsize;
> + } else if (ndisks) {
[Severity: High]
This isn't a bug introduced by this patch, but the patch attempts to fix
leaks in this error path and structurally misses this one. When Step 4 of
resize_stripes() fails to allocate a page for the new stripe slots
(nsh->dev[i].page), err is set to -ENOMEM and the pool_size update is
skipped here.
During array teardown, shrink_buffers() iterates only up to
sh->raid_conf->pool_size:
drivers/md/raid5.c:shrink_buffers() {
...
int num = sh->raid_conf->pool_size;
#if PAGE_SIZE == DEFAULT_STRIPE_SIZE
for (i = 0; i < num ; i++) {
...
}
Are the successfully allocated pages at indices >= pool_size permanently
leaked when free_stripe() destroys the slab object, because the cleanup loop
misses them?
> + for (i = conf->pool_size; i < newsize; i++)
> + if (ndisks[i].extra_page)
> + put_page(ndisks[i].extra_page);
> + kfree(ndisks);
> + }
> mutex_unlock(&conf->cache_size_mutex);
>
> return err;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260827060554.77849-1-ghuicao@163.com?part=2
next prev parent reply other threads:[~2026-08-27 6:27 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-27 2:38 [PATCH] md/raid5: set pool_size before extra_page allocation to fix leak on error path ghuicao
2026-08-27 2:53 ` sashiko-bot
2026-08-27 6:05 ` [PATCH v2 1/3] " ghuicao
2026-08-27 6:05 ` [PATCH v2 2/3] md/raid5: fix leak and use-after-free in resize_stripes " ghuicao
2026-08-27 6:27 ` sashiko-bot [this message]
2026-08-27 6:05 ` [PATCH v2 3/3] md/raid5: fix NULL pointer dereference in raid5_free_percpu ghuicao
2026-08-27 6:18 ` sashiko-bot
2026-08-27 6:27 ` [PATCH v2 1/3] md/raid5: set pool_size before extra_page allocation to fix leak on error path sashiko-bot
2026-08-27 6:32 ` [PATCH v3 " ghuicao
2026-08-27 6:32 ` [PATCH v3 2/3] md/raid5: fix leak and use-after-free in resize_stripes " ghuicao
2026-08-27 7:02 ` sashiko-bot
2026-08-27 6:32 ` [PATCH v3 3/3] md/raid5: fix NULL pointer dereference in raid5_free_percpu ghuicao
2026-08-27 7:17 ` sashiko-bot
2026-08-27 8:03 ` [PATCH v4 1/2] md/raid5: track disks array size to fix extra_page leak on error paths ghuicao
2026-08-27 8:03 ` [PATCH v4 2/2] md/raid5: fix NULL pointer dereference in raid5_free_percpu ghuicao
2026-08-27 8:19 ` [PATCH v4 1/2] md/raid5: track disks array size to fix extra_page leak on error paths sashiko-bot
2026-09-05 2:34 ` yu kuai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260827062751.768881F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=ghuicao@163.com \
--cc=linux-raid@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=yukuai@fygo.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.