Message ID | 02fc507b62b19be2348fc08de8b13bd7af1a440e.1728922973.git.fdmanana@suse.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs: fix use-after-free on head ref when adding delayed ref | expand |
On Mon, Oct 14, 2024 at 05:24:26PM +0100, fdmanana@kernel.org wrote: > From: Filipe Manana <fdmanana@suse.com> > > At add_delayed_ref(), if we added a qgroup record, we can trigger a > use-after-free on the head reference when calling > btrfs_qgroup_trace_extent_post() since we are not holding the delayed refs > spinlock anymore at that point and in the meanwhile other task may have > removed the head reference after running delayed refs. > > So fix this by extracting the bytenr from the generic reference instead > of the head reference. > > Reported-by: syzbot+c3a3a153f0190dca5be9@syzkaller.appspotmail.com > Link: https://lore.kernel.org/linux-btrfs/670d3f2c.050a0220.3e960.0066.GAE@google.com/ > Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: Boris Burkov <boris@bur.io> > --- > > This is meant to be squashed into the following patch that is in for-next > but not in Linus' tree: > > "btrfs: qgroups: remove bytenr field from struct btrfs_qgroup_extent_record" > > fs/btrfs/delayed-ref.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c > index 13c2e00d1270..04586aa11917 100644 > --- a/fs/btrfs/delayed-ref.c > +++ b/fs/btrfs/delayed-ref.c > @@ -1074,7 +1074,7 @@ static int add_delayed_ref(struct btrfs_trans_handle *trans, > kmem_cache_free(btrfs_delayed_ref_node_cachep, node); > > if (qrecord_inserted) > - return btrfs_qgroup_trace_extent_post(trans, record, head_ref->bytenr); > + return btrfs_qgroup_trace_extent_post(trans, record, generic_ref->bytenr); > return 0; > > free_record: > -- > 2.43.0 >
在 2024/10/15 02:54, fdmanana@kernel.org 写道: > From: Filipe Manana <fdmanana@suse.com> > > At add_delayed_ref(), if we added a qgroup record, we can trigger a > use-after-free on the head reference when calling > btrfs_qgroup_trace_extent_post() since we are not holding the delayed refs > spinlock anymore at that point and in the meanwhile other task may have > removed the head reference after running delayed refs. > > So fix this by extracting the bytenr from the generic reference instead > of the head reference. > > Reported-by: syzbot+c3a3a153f0190dca5be9@syzkaller.appspotmail.com > Link: https://lore.kernel.org/linux-btrfs/670d3f2c.050a0220.3e960.0066.GAE@google.com/ > Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: Qu Wenruo <wqu@suse.com> Thanks, Qu > --- > > This is meant to be squashed into the following patch that is in for-next > but not in Linus' tree: > > "btrfs: qgroups: remove bytenr field from struct btrfs_qgroup_extent_record" > > fs/btrfs/delayed-ref.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c > index 13c2e00d1270..04586aa11917 100644 > --- a/fs/btrfs/delayed-ref.c > +++ b/fs/btrfs/delayed-ref.c > @@ -1074,7 +1074,7 @@ static int add_delayed_ref(struct btrfs_trans_handle *trans, > kmem_cache_free(btrfs_delayed_ref_node_cachep, node); > > if (qrecord_inserted) > - return btrfs_qgroup_trace_extent_post(trans, record, head_ref->bytenr); > + return btrfs_qgroup_trace_extent_post(trans, record, generic_ref->bytenr); > return 0; > > free_record:
On Mon, Oct 14, 2024 at 05:24:26PM +0100, fdmanana@kernel.org wrote: > From: Filipe Manana <fdmanana@suse.com> > > At add_delayed_ref(), if we added a qgroup record, we can trigger a > use-after-free on the head reference when calling > btrfs_qgroup_trace_extent_post() since we are not holding the delayed refs > spinlock anymore at that point and in the meanwhile other task may have > removed the head reference after running delayed refs. > > So fix this by extracting the bytenr from the generic reference instead > of the head reference. > > Reported-by: syzbot+c3a3a153f0190dca5be9@syzkaller.appspotmail.com > Link: https://lore.kernel.org/linux-btrfs/670d3f2c.050a0220.3e960.0066.GAE@google.com/ > Signed-off-by: Filipe Manana <fdmanana@suse.com> > --- > > This is meant to be squashed into the following patch that is in for-next > but not in Linus' tree: > > "btrfs: qgroups: remove bytenr field from struct btrfs_qgroup_extent_record" Thanks, I've updated the for-next branches and now it should be all sorted.
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c index 13c2e00d1270..04586aa11917 100644 --- a/fs/btrfs/delayed-ref.c +++ b/fs/btrfs/delayed-ref.c @@ -1074,7 +1074,7 @@ static int add_delayed_ref(struct btrfs_trans_handle *trans, kmem_cache_free(btrfs_delayed_ref_node_cachep, node); if (qrecord_inserted) - return btrfs_qgroup_trace_extent_post(trans, record, head_ref->bytenr); + return btrfs_qgroup_trace_extent_post(trans, record, generic_ref->bytenr); return 0; free_record: