fs/btrfs/ioctl.c | 5 +++++ 1 file changed, 5 insertions(+)
r0 = open(&(0x7f0000000080)='./file0\x00', 0x0, 0x0)
ioctl$BTRFS_IOC_QUOTA_CTL(r0, 0xc0109428, &(0x7f0000000000)={0x1})
r1 = openat$cgroup_ro(0xffffffffffffff9c, &(0x7f0000000100)='blkio.bfq.time_recursive\x00', 0x275a, 0x0)
ioctl$BTRFS_IOC_QGROUP_CREATE(r1, 0x4010942a, &(0x7f0000000640)={0x1, 0x100})
r2 = openat(0xffffffffffffff9c, &(0x7f0000000500)='.\x00', 0x0, 0x0)
ioctl$BTRFS_IOC_SNAP_CREATE(r0, 0x50009401, &(0x7f0000000a80)={{r2},
From the logs, it can be seen that syz can execute to btrfs_ioctl_qgroup_create()
through two paths.
Syz enters btrfs_ioctl_qgroup_create() by calling ioctl$BTRFS_IOC_QGROUP_CREATE(
r1, 0x4010942a,&(0x7f000000 640)={0x1, 0x100}) or ioctl$BTRFS_IOC_SNAP_CREATE(r0,
0x50009401,&(0x7f000000 a80)={r2}," respectively;
The most crucial thing is that when calling ioctl$BTRFS_IOC_QGROUP_CREATE,
the passed parameter qgroupid value is 256, while BTRFS_FIRST_FREE_OBJECTID
is also equal to 256, indicating that the passed parameter qgroupid is
obviously incorrect.
Reported-and-tested-by: syzbot+4d81015bc10889fd12ea@syzkaller.appspotmail.com
Fixes: 6ed05643ddb1 ("btrfs: create qgroup earlier in snapshot creation")
Signed-off-by: Lizhi Xu <lizhi.xu@windriver.com>
---
fs/btrfs/ioctl.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 752acff2c734..21cf7a7f18ab 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3799,6 +3799,11 @@ static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg)
goto out;
}
+ if (sa->create && sa->qgroupid == BTRFS_FIRST_FREE_OBJECTID) {
+ ret = -EINVAL;
+ goto out;
+ }
+
trans = btrfs_join_transaction(root);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
--
2.25.1
On 2023/11/10 22:18, Lizhi Xu wrote:
> r0 = open(&(0x7f0000000080)='./file0\x00', 0x0, 0x0)
> ioctl$BTRFS_IOC_QUOTA_CTL(r0, 0xc0109428, &(0x7f0000000000)={0x1})
> r1 = openat$cgroup_ro(0xffffffffffffff9c, &(0x7f0000000100)='blkio.bfq.time_recursive\x00', 0x275a, 0x0)
> ioctl$BTRFS_IOC_QGROUP_CREATE(r1, 0x4010942a, &(0x7f0000000640)={0x1, 0x100})
> r2 = openat(0xffffffffffffff9c, &(0x7f0000000500)='.\x00', 0x0, 0x0)
> ioctl$BTRFS_IOC_SNAP_CREATE(r0, 0x50009401, &(0x7f0000000a80)={{r2},
>
> From the logs, it can be seen that syz can execute to btrfs_ioctl_qgroup_create()
> through two paths.
> Syz enters btrfs_ioctl_qgroup_create() by calling ioctl$BTRFS_IOC_QGROUP_CREATE(
> r1, 0x4010942a,&(0x7f000000 640)={0x1, 0x100}) or ioctl$BTRFS_IOC_SNAP_CREATE(r0,
> 0x50009401,&(0x7f000000 a80)={r2}," respectively;
>
> The most crucial thing is that when calling ioctl$BTRFS_IOC_QGROUP_CREATE,
> the passed parameter qgroupid value is 256, while BTRFS_FIRST_FREE_OBJECTID
> is also equal to 256, indicating that the passed parameter qgroupid is
> obviously incorrect.
This conclusion looks incorrect to me.
Subvolumes are allowed to have any id in the range
[BTRFS_FIRST_TREE_OBJECTID, BTRFS_LAST_TREE_OBJECTID].
In fact, you can easily create a subvolume with 256 as its subvolumeid.
Just create an empty fs, and create a new subvolume in it, then you got;
item 11 key (256 ROOT_ITEM 0) itemoff 12961 itemsize 439
generation 7 root_dirid 256 bytenr 30441472 byte_limit 0 bytes_used 16384
...
So it's completely valid.
The root cause is just snapshot creation conflicts with an existing qgroup.
Thanks,
Qu
>
> Reported-and-tested-by: syzbot+4d81015bc10889fd12ea@syzkaller.appspotmail.com
> Fixes: 6ed05643ddb1 ("btrfs: create qgroup earlier in snapshot creation")
> Signed-off-by: Lizhi Xu <lizhi.xu@windriver.com>
> ---
> fs/btrfs/ioctl.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
> index 752acff2c734..21cf7a7f18ab 100644
> --- a/fs/btrfs/ioctl.c
> +++ b/fs/btrfs/ioctl.c
> @@ -3799,6 +3799,11 @@ static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg)
> goto out;
> }
>
> + if (sa->create && sa->qgroupid == BTRFS_FIRST_FREE_OBJECTID) { > + ret = -EINVAL;
> + goto out;
> + }
> +
> trans = btrfs_join_transaction(root);
> if (IS_ERR(trans)) {
> ret = PTR_ERR(trans);
© 2016 - 2025 Red Hat, Inc.