在 2026/4/8 12:35, Benjamin Marzinski 写道: > If make_stripe_request() returns STRIPE_WAIT_RESHAPE, > raid5_make_request() will free the cloned bio. But raid5_make_request() > can call make_stripe_request() multiple times, writing to the various > stripes. If that bio got added to the toread or towrite lists of a > stripe disk in an earlier call to make_stripe_request(), then it's not > safe to just free the bio if a later part of it is found to cross the > reshape position. Doing so can lead to a UAF error, when bio_endio() > is called on the bio for the earlier stripes. > > Instead, raid5_make_request() needs to wait until all parts of the bio > have called bio_endio(). To do this, bios that cross the reshape > position while the reshape can't make progress are flagged as needing to > wait for all parts to complete. When raid5_make_request() has a bio that > failed make_stripe_request() with STRIPE_WAIT_RESHAPE, it sets > bi->bi_private to a completion struct and waits for completion after > ending the bio. When the bio_endio() is called for the last time on a > clone bio with bi->bi_private set, it wakes up the waiter. This > guarantees that raid5_make_request() doesn't return until the cloned bio > needing a retry for io across the reshape boundary is safely cleaned up. > > There is a simple reproducer available at [1]. Compile the kernel with > KASAN for more useful reporting when the error is triggered (this is not > necessary to see the bug). > > [1]https://gist.github.com/bmarzins/e48598824305cf2171289e47d7241fa5 > > Signed-off-by: Benjamin Marzinski<[email protected]> > --- > > Changes from v1: > - Removed mddev->pending_retry_bios, mddev->retry_bios_wait, and > md_io_clone->must_retry. Instead, use a completion struct > pointed to by bi->bi_private, as suggested by Xiao Ni and Yu Kuai. > > drivers/md/md.c | 31 ++++++++----------------------- > drivers/md/md.h | 1 - > drivers/md/raid5.c | 7 ++++++- > 3 files changed, 14 insertions(+), 25 deletions(-) Applied
-- Thansk, Kuai
