Re: [PATCH] btrfs: fix transaction use-after-free in raid stripe insertion
Shuangpeng <[email protected]>
| Newsgroups | org.kernel.vger.linux-btrfs |
|---|---|
| Message-ID | <[email protected]> |
> On Aug 16, 2026, at 21:58, Qu Wenruo <[email protected]> wrote: > > > > 在 2026/8/17 10:57, Shuangpeng Bai 写道: >> If allocation of a RAID stripe extent fails, >> btrfs_insert_one_raid_extent() aborts and ends the transaction before >> returning -ENOMEM. >> btrfs_finish_one_ordered(), the production caller through >> btrfs_insert_raid_extent(), still owns the transaction handle. It handles >> the error by aborting the transaction and then reaches the common exit >> path, which ends the transaction again. >> The premature end can free the handle and drop its transaction reference. >> Transaction cleanup can then free the transaction before the caller's >> second abort accesses the handle and transaction, resulting in >> use-after-free. >> Keep the abort at the failure site, but let the caller's common exit path >> end the transaction once, after it has finished using both objects. >> Fixes: 02c372e1f016 ("btrfs: add support for inserting raid stripe extents") >> Cc: [email protected] > > Please disclose LLM usage. > Hi Qu, Thanks for pointing this out. I used Codex to help generate the patch. I had confirmed the bug with KASAN, and I also verified the proposed fix with my reproducer. With the patch applied, the reproducer no longer triggers the KASAN report. I will send a v2 with the appropriate LLM disclosure tag. Thanks, Shuangpeng >> Signed-off-by: Shuangpeng Bai <[email protected]> >> --- >> fs/btrfs/raid-stripe-tree.c | 1 - >> 1 file changed, 1 deletion(-) >> diff --git a/fs/btrfs/raid-stripe-tree.c b/fs/btrfs/raid-stripe-tree.c >> index b210371ce91e..89e259a47d8d 100644 >> --- a/fs/btrfs/raid-stripe-tree.c >> +++ b/fs/btrfs/raid-stripe-tree.c >> @@ -337,7 +337,6 @@ int btrfs_insert_one_raid_extent(struct btrfs_trans_handle *trans, >> stripe_extent = kzalloc(item_size, GFP_NOFS); >> if (unlikely(!stripe_extent)) { >> btrfs_abort_transaction(trans, -ENOMEM); >> - btrfs_end_transaction(trans); >> return -ENOMEM; >> } >> >