* [PATCH] ocfs2: add extra flags check in ocfs2_ioctl_move_extents()
@ 2025-10-08 11:20 Dmitry Antipov
2025-10-09 2:15 ` Joseph Qi
0 siblings, 1 reply; 11+ messages in thread
From: Dmitry Antipov @ 2025-10-08 11:20 UTC (permalink / raw)
To: Mark Fasheh, Joel Becker, Joseph Qi
Cc: ocfs2-devel, lvc-project, Dmitry Antipov,
syzbot+727d161855d11d81e411
In 'ocfs2_ioctl_move_extents()', add extra check whether only actually
supported flags are passed via 'ioctl(..., OCFS2_IOC_MOVE_EXT, ...)',
and reject anything beyond OCFS2_MOVE_EXT_FL_AUTO_DEFRAG and
OCFS2_MOVE_EXT_FL_PART_DEFRAG with -EINVAL. In particular,
OCFS2_MOVE_EXT_FL_COMPLETE may be set by the kernel only and
should never be passed from userspace.
Reported-by: syzbot+727d161855d11d81e411@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=727d161855d11d81e411
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
---
fs/ocfs2/move_extents.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c
index 86f2631e6360..e038c009cdef 100644
--- a/fs/ocfs2/move_extents.c
+++ b/fs/ocfs2/move_extents.c
@@ -1031,6 +1031,12 @@ int ocfs2_ioctl_move_extents(struct file *filp, void __user *argp)
if (range.me_threshold > i_size_read(inode))
range.me_threshold = i_size_read(inode);
+ if (range.me_flags & ~(OCFS2_MOVE_EXT_FL_AUTO_DEFRAG |
+ OCFS2_MOVE_EXT_FL_PART_DEFRAG)) {
+ status = -EINVAL;
+ goto out_free;
+ }
+
if (range.me_flags & OCFS2_MOVE_EXT_FL_AUTO_DEFRAG) {
context->auto_defrag = 1;
--
2.51.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH] ocfs2: add extra flags check in ocfs2_ioctl_move_extents()
2025-10-08 11:20 [PATCH] ocfs2: add extra flags check in ocfs2_ioctl_move_extents() Dmitry Antipov
@ 2025-10-09 2:15 ` Joseph Qi
2025-10-09 6:39 ` Dmitry Antipov
0 siblings, 1 reply; 11+ messages in thread
From: Joseph Qi @ 2025-10-09 2:15 UTC (permalink / raw)
To: Dmitry Antipov, Mark Fasheh, Joel Becker
Cc: ocfs2-devel, lvc-project, syzbot+727d161855d11d81e411
On 2025/10/8 19:20, Dmitry Antipov wrote:
> In 'ocfs2_ioctl_move_extents()', add extra check whether only actually
> supported flags are passed via 'ioctl(..., OCFS2_IOC_MOVE_EXT, ...)',
> and reject anything beyond OCFS2_MOVE_EXT_FL_AUTO_DEFRAG and
> OCFS2_MOVE_EXT_FL_PART_DEFRAG with -EINVAL. In particular,
> OCFS2_MOVE_EXT_FL_COMPLETE may be set by the kernel only and
> should never be passed from userspace.
>
> Reported-by: syzbot+727d161855d11d81e411@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=727d161855d11d81e411
> Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
> ---
> fs/ocfs2/move_extents.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c
> index 86f2631e6360..e038c009cdef 100644
> --- a/fs/ocfs2/move_extents.c
> +++ b/fs/ocfs2/move_extents.c
> @@ -1031,6 +1031,12 @@ int ocfs2_ioctl_move_extents(struct file *filp, void __user *argp)
> if (range.me_threshold > i_size_read(inode))
> range.me_threshold = i_size_read(inode);
>
> + if (range.me_flags & ~(OCFS2_MOVE_EXT_FL_AUTO_DEFRAG |
> + OCFS2_MOVE_EXT_FL_PART_DEFRAG)) {
> + status = -EINVAL;
> + goto out_free;
> + }
> +
The check here looks fine.
Could you please elaborate more how it fixes the reported bug?
Thanks,
Joseph
> if (range.me_flags & OCFS2_MOVE_EXT_FL_AUTO_DEFRAG) {
> context->auto_defrag = 1;
>
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH] ocfs2: add extra flags check in ocfs2_ioctl_move_extents()
2025-10-09 2:15 ` Joseph Qi
@ 2025-10-09 6:39 ` Dmitry Antipov
2025-10-09 7:51 ` Joseph Qi
0 siblings, 1 reply; 11+ messages in thread
From: Dmitry Antipov @ 2025-10-09 6:39 UTC (permalink / raw)
To: Joseph Qi, Mark Fasheh, Joel Becker
Cc: ocfs2-devel, lvc-project, syzbot+727d161855d11d81e411
On 10/9/25 5:15 AM, Joseph Qi wrote:
> The check here looks fine.
> Could you please elaborate more how it fixes the reported bug?
Ugh. This just catches the reproducer early, thus stopping it the way
before the actual BUG() is triggered :-(.
According to fsck.ocfs2, the filesystem used by the reproducer in this
particular case is totally broken and even fsck.ocfs2 is unable to
repair it automatically:
fsck.ocfs2 1.8.8
Checking OCFS2 filesystem in /dev/loop0:
Label: <NONE>
UUID: B1DE653C5FFC4D88B33B244AAB9EB3E9
Number of blocks: 16384
Block size: 512
Number of clusters: 1024
Cluster size: 8192
Number of slots: 1
/dev/loop0 was run with -f, check forced.
Pass 0a: Checking cluster allocation chains
[GROUP_FREE_BITS] Group descriptor at block 32 claims to have 427 free bits which is more than 420 bits indicated by the bitmap. Drop its free bit count down to the total? y
[CHAIN_BITS] Chain 0 in allocator inode 71 has 427 bits marked free out of 1024 total bits but the block groups in the chain have 420 free out of 1024 total. Fix this by updating the chain record? y
[CHAIN_GROUP_BITS] Allocator inode 71 has 597 bits marked used out of 1024 total bits but the chains have 604 used out of 1024 total. Fix this by updating the inode counts? y
[CHAIN_I_SIZE] Allocator inode 71 has 1024 clusters represented in its allocator chain which accounts for 8388608 total bytes, but its i_size is 16777216. Fix this by updating i_size? y
Pass 0b: Checking inode allocation chains
[CHAIN_I_SIZE] Allocator inode 68 has 288 clusters represented in its allocator chain which accounts for 73728 total bytes, but its i_size is 147456. Fix this by updating i_size? y
[CHAIN_HEAD_LINK_RANGE] Chain 0 in allocator inode 74 contains an initial block reference to 17056 which is out of range. Clear this reference? y
[CHAIN_BITS] Chain 0 in allocator inode 74 has 2046 bits marked free out of 2048 total bits but the block groups in the chain have 0 free out of 0 total. Fix this by updating the chain record? y
[CHAIN_EMPTY] Chain 0 in allocator inode 74 is empty. Remove it from the chain record array in the inode and shift further chains into its place? y
[CHAIN_GROUP_BITS] Allocator inode 74 has 2 bits marked used out of 2048 total bits but the chains have 0 used out of 0 total. Fix this by updating the inode counts? y
[CHAIN_I_CLUSTERS] Allocator inode 74 has 0 clusters represented in its allocator chains but has an i_clusters value of 64. Fix this by updating i_clusters? y
[CHAIN_I_SIZE] Allocator inode 74 has 0 clusters represented in its allocator chain which accounts for 0 total bytes, but its i_size is 1048576. Fix this by updating i_size? y
Pass 0c: Checking extent block allocation chains
[CHAIN_I_SIZE] Allocator inode 73 has 0 clusters represented in its allocator chain which accounts for 0 total bytes, but its i_size is 90133. Fix this by updating i_size? y
Pass 1: Checking inodes and blocks
pass1: Internal logic failure while trying to set inode 65's allocation to '1'. None of the slots chain allocator's had a group covering the inode.
pass1: Internal logic failure while trying to set inode 66's allocation to '1'. None of the slots chain allocator's had a group covering the inode.
pass1: Internal logic failure while trying to set inode 67's allocation to '1'. None of the slots chain allocator's had a group covering the inode.
pass1: Internal logic failure while trying to set inode 68's allocation to '1'. None of the slots chain allocator's had a group covering the inode.
[EXTENT_BLKNO_RANGE] Extent record 0 in owner 69 refers to a block that is out of range. Remove this record from the extent list? y
[INODE_SPARSE_CLUSTERS] Inode 69 has 1 clusters but its blocks fit in 0 clusters. Correct the number of clusters? y
pass1: Internal logic failure while trying to set inode 69's allocation to '1'. None of the slots chain allocator's had a group covering the inode.
...
[INODE_ALLOC_REPAIR] Inode 128 is marked as invalid but its position in the inode allocator is marked as in use. Fix the allocation of this and all future inodes? y
[CLUSTER_ALLOC_BIT] Cluster 3 is marked in the global cluster bitmap but it isn't in use. Clear its bit in the bitmap? y
...
Pass 2: Checking directory entries
pass2: Bit does not exist in bitmap range while testing if inode 65 is allocated. Continuing as though it is.
pass2: Bit does not exist in bitmap range while testing if inode 65 is allocated. Continuing as though it is.
pass2: Bit does not exist in bitmap range while testing if inode 65 is allocated. Continuing as though it is.
[DIRENT_INODE_RANGE] Directory entry 'lost+found' refers to inode number 17057 which is out of range, clear the entry? y
pass2: Bit does not exist in bitmap range while testing if inode 72 is allocated. Continuing as though it is.
[DIRENT_NOT_DOTTY] The first directory entry in directory inode 72 is '' instead of '.'. Clobber the current name with the expected dot name? y
pass2: Bit does not exist in bitmap range while testing if inode 72 is allocated. Continuing as though it is.
pass2: Bit does not exist in bitmap range while testing if inode 66 is allocated. Continuing as though it is.
pass2: Bit does not exist in bitmap range while testing if inode 66 is allocated. Continuing as though it is.
[DX_TREE_MISSING] Directory 66 is missing index. Rebuild? y
...
pass2: Invalid block number while rebuild indexed dirs.
fsck.ocfs2: Invalid block number while performing pass 2
(exited with status 8)
I assume that any attempt to modify anything on such a filesystem just makes
the things even worse. So what about just relaxing BUG() to ocfs2_error(), i.e.
diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c
index 86f2631e6360..bf3f3f0f6eb5 100644
--- a/fs/ocfs2/move_extents.c
+++ b/fs/ocfs2/move_extents.c
@@ -98,7 +98,13 @@ static int __ocfs2_move_extent(handle_t *handle,
rec = &el->l_recs[index];
- BUG_ON(ext_flags != rec->e_flags);
+ if (ext_flags != rec->e_flags) {
+ ret = ocfs2_error(inode->i_sb,
+ "Inode %llu has corrupted extent %d at cpos %u\n",
+ (unsigned long long)ino, index, cpos);
+ goto out;
+ }
+
/*
* after moving/defraging to new location, the extent is not going
* to be refcounted anymore.
Dmitry
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH] ocfs2: add extra flags check in ocfs2_ioctl_move_extents()
2025-10-09 6:39 ` Dmitry Antipov
@ 2025-10-09 7:51 ` Joseph Qi
2025-10-09 10:23 ` [PATCH 1/2] " Dmitry Antipov
2025-10-09 10:25 ` [PATCH] " Dmitry Antipov
0 siblings, 2 replies; 11+ messages in thread
From: Joseph Qi @ 2025-10-09 7:51 UTC (permalink / raw)
To: Dmitry Antipov, Mark Fasheh, Joel Becker
Cc: ocfs2-devel, lvc-project, syzbot+727d161855d11d81e411
On 2025/10/9 14:39, Dmitry Antipov wrote:
> On 10/9/25 5:15 AM, Joseph Qi wrote:
>
>> The check here looks fine.
>> Could you please elaborate more how it fixes the reported bug?
>
> Ugh. This just catches the reproducer early, thus stopping it the way
> before the actual BUG() is triggered :-(.
>
So you mean the reproducer passes OCFS2_MOVE_EXT_FL_COMPLETE through
ioctl and then trigger this BUG?
> According to fsck.ocfs2, the filesystem used by the reproducer in this
> particular case is totally broken and even fsck.ocfs2 is unable to
> repair it automatically:
>
> fsck.ocfs2 1.8.8
> Checking OCFS2 filesystem in /dev/loop0:
> Label: <NONE>
> UUID: B1DE653C5FFC4D88B33B244AAB9EB3E9
> Number of blocks: 16384
> Block size: 512
> Number of clusters: 1024
> Cluster size: 8192
> Number of slots: 1
>
> /dev/loop0 was run with -f, check forced.
> Pass 0a: Checking cluster allocation chains
> [GROUP_FREE_BITS] Group descriptor at block 32 claims to have 427 free bits which is more than 420 bits indicated by the bitmap. Drop its free bit count down to the total? y
> [CHAIN_BITS] Chain 0 in allocator inode 71 has 427 bits marked free out of 1024 total bits but the block groups in the chain have 420 free out of 1024 total. Fix this by updating the chain record? y
> [CHAIN_GROUP_BITS] Allocator inode 71 has 597 bits marked used out of 1024 total bits but the chains have 604 used out of 1024 total. Fix this by updating the inode counts? y
> [CHAIN_I_SIZE] Allocator inode 71 has 1024 clusters represented in its allocator chain which accounts for 8388608 total bytes, but its i_size is 16777216. Fix this by updating i_size? y
> Pass 0b: Checking inode allocation chains
> [CHAIN_I_SIZE] Allocator inode 68 has 288 clusters represented in its allocator chain which accounts for 73728 total bytes, but its i_size is 147456. Fix this by updating i_size? y
> [CHAIN_HEAD_LINK_RANGE] Chain 0 in allocator inode 74 contains an initial block reference to 17056 which is out of range. Clear this reference? y
> [CHAIN_BITS] Chain 0 in allocator inode 74 has 2046 bits marked free out of 2048 total bits but the block groups in the chain have 0 free out of 0 total. Fix this by updating the chain record? y
> [CHAIN_EMPTY] Chain 0 in allocator inode 74 is empty. Remove it from the chain record array in the inode and shift further chains into its place? y
> [CHAIN_GROUP_BITS] Allocator inode 74 has 2 bits marked used out of 2048 total bits but the chains have 0 used out of 0 total. Fix this by updating the inode counts? y
> [CHAIN_I_CLUSTERS] Allocator inode 74 has 0 clusters represented in its allocator chains but has an i_clusters value of 64. Fix this by updating i_clusters? y
> [CHAIN_I_SIZE] Allocator inode 74 has 0 clusters represented in its allocator chain which accounts for 0 total bytes, but its i_size is 1048576. Fix this by updating i_size? y
> Pass 0c: Checking extent block allocation chains
> [CHAIN_I_SIZE] Allocator inode 73 has 0 clusters represented in its allocator chain which accounts for 0 total bytes, but its i_size is 90133. Fix this by updating i_size? y
> Pass 1: Checking inodes and blocks
> pass1: Internal logic failure while trying to set inode 65's allocation to '1'. None of the slots chain allocator's had a group covering the inode.
> pass1: Internal logic failure while trying to set inode 66's allocation to '1'. None of the slots chain allocator's had a group covering the inode.
> pass1: Internal logic failure while trying to set inode 67's allocation to '1'. None of the slots chain allocator's had a group covering the inode.
> pass1: Internal logic failure while trying to set inode 68's allocation to '1'. None of the slots chain allocator's had a group covering the inode.
> [EXTENT_BLKNO_RANGE] Extent record 0 in owner 69 refers to a block that is out of range. Remove this record from the extent list? y
> [INODE_SPARSE_CLUSTERS] Inode 69 has 1 clusters but its blocks fit in 0 clusters. Correct the number of clusters? y
> pass1: Internal logic failure while trying to set inode 69's allocation to '1'. None of the slots chain allocator's had a group covering the inode.
> ...
> [INODE_ALLOC_REPAIR] Inode 128 is marked as invalid but its position in the inode allocator is marked as in use. Fix the allocation of this and all future inodes? y
> [CLUSTER_ALLOC_BIT] Cluster 3 is marked in the global cluster bitmap but it isn't in use. Clear its bit in the bitmap? y
> ...
> Pass 2: Checking directory entries
> pass2: Bit does not exist in bitmap range while testing if inode 65 is allocated. Continuing as though it is.
> pass2: Bit does not exist in bitmap range while testing if inode 65 is allocated. Continuing as though it is.
> pass2: Bit does not exist in bitmap range while testing if inode 65 is allocated. Continuing as though it is.
> [DIRENT_INODE_RANGE] Directory entry 'lost+found' refers to inode number 17057 which is out of range, clear the entry? y
> pass2: Bit does not exist in bitmap range while testing if inode 72 is allocated. Continuing as though it is.
> [DIRENT_NOT_DOTTY] The first directory entry in directory inode 72 is '' instead of '.'. Clobber the current name with the expected dot name? y
> pass2: Bit does not exist in bitmap range while testing if inode 72 is allocated. Continuing as though it is.
> pass2: Bit does not exist in bitmap range while testing if inode 66 is allocated. Continuing as though it is.
> pass2: Bit does not exist in bitmap range while testing if inode 66 is allocated. Continuing as though it is.
> [DX_TREE_MISSING] Directory 66 is missing index. Rebuild? y
> ...
> pass2: Invalid block number while rebuild indexed dirs.
> fsck.ocfs2: Invalid block number while performing pass 2
>
> (exited with status 8)
>
> I assume that any attempt to modify anything on such a filesystem just makes
> the things even worse. So what about just relaxing BUG() to ocfs2_error(), i.e.
>
> diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c
> index 86f2631e6360..bf3f3f0f6eb5 100644
> --- a/fs/ocfs2/move_extents.c
> +++ b/fs/ocfs2/move_extents.c
> @@ -98,7 +98,13 @@ static int __ocfs2_move_extent(handle_t *handle,
>
> rec = &el->l_recs[index];
>
> - BUG_ON(ext_flags != rec->e_flags);
> + if (ext_flags != rec->e_flags) {
> + ret = ocfs2_error(inode->i_sb,
> + "Inode %llu has corrupted extent %d at cpos %u\n",
> + (unsigned long long)ino, index, cpos);
> + goto out;
> + }
> +
This looks more sane and seems directly fix the BUG.
BTW, we'd better also log the extent flags.
Thanks,
Joseph
> /*
> * after moving/defraging to new location, the extent is not going
> * to be refcounted anymore.
>
> Dmitry
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH 1/2] ocfs2: add extra flags check in ocfs2_ioctl_move_extents()
2025-10-09 7:51 ` Joseph Qi
@ 2025-10-09 10:23 ` Dmitry Antipov
2025-10-09 10:23 ` [PATCH 2/2] ocfs2: relax BUG() to ocfs2_error() in __ocfs2_move_extent() Dmitry Antipov
2025-10-09 11:07 ` [PATCH 1/2] ocfs2: add extra flags check in ocfs2_ioctl_move_extents() Joseph Qi
2025-10-09 10:25 ` [PATCH] " Dmitry Antipov
1 sibling, 2 replies; 11+ messages in thread
From: Dmitry Antipov @ 2025-10-09 10:23 UTC (permalink / raw)
To: Mark Fasheh, Joel Becker, Joseph Qi
Cc: ocfs2-devel, lvc-project, Dmitry Antipov
In 'ocfs2_ioctl_move_extents()', add extra check whether only actually
supported flags are passed via 'ioctl(..., OCFS2_IOC_MOVE_EXT, ...)',
and reject anything beyond OCFS2_MOVE_EXT_FL_AUTO_DEFRAG and
OCFS2_MOVE_EXT_FL_PART_DEFRAG with -EINVAL. In particular,
OCFS2_MOVE_EXT_FL_COMPLETE may be set by the kernel only and
should never be passed from userspace.
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
---
fs/ocfs2/move_extents.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c
index 86f2631e6360..e038c009cdef 100644
--- a/fs/ocfs2/move_extents.c
+++ b/fs/ocfs2/move_extents.c
@@ -1031,6 +1031,12 @@ int ocfs2_ioctl_move_extents(struct file *filp, void __user *argp)
if (range.me_threshold > i_size_read(inode))
range.me_threshold = i_size_read(inode);
+ if (range.me_flags & ~(OCFS2_MOVE_EXT_FL_AUTO_DEFRAG |
+ OCFS2_MOVE_EXT_FL_PART_DEFRAG)) {
+ status = -EINVAL;
+ goto out_free;
+ }
+
if (range.me_flags & OCFS2_MOVE_EXT_FL_AUTO_DEFRAG) {
context->auto_defrag = 1;
--
2.51.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH 2/2] ocfs2: relax BUG() to ocfs2_error() in __ocfs2_move_extent()
2025-10-09 10:23 ` [PATCH 1/2] " Dmitry Antipov
@ 2025-10-09 10:23 ` Dmitry Antipov
2025-10-09 11:12 ` Joseph Qi
2025-10-09 11:07 ` [PATCH 1/2] ocfs2: add extra flags check in ocfs2_ioctl_move_extents() Joseph Qi
1 sibling, 1 reply; 11+ messages in thread
From: Dmitry Antipov @ 2025-10-09 10:23 UTC (permalink / raw)
To: Mark Fasheh, Joel Becker, Joseph Qi
Cc: ocfs2-devel, lvc-project, Dmitry Antipov,
syzbot+727d161855d11d81e411
In '__ocfs2_move_extent()', relax 'BUG()' to 'ocfs2_error()' just
to avoid crashing the whole kernel due to a filesystem corruption.
Reported-by: syzbot+727d161855d11d81e411@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=727d161855d11d81e411
Fixes: 8f603e567aa7 ("Ocfs2/move_extents: move a range of extent.")
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
---
fs/ocfs2/move_extents.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c
index e038c009cdef..ba4952b41602 100644
--- a/fs/ocfs2/move_extents.c
+++ b/fs/ocfs2/move_extents.c
@@ -98,7 +98,13 @@ static int __ocfs2_move_extent(handle_t *handle,
rec = &el->l_recs[index];
- BUG_ON(ext_flags != rec->e_flags);
+ if (ext_flags != rec->e_flags) {
+ ret = ocfs2_error(inode->i_sb,
+ "Inode %llu has corrupted extent %d with flags 0x%x at cpos %u\n",
+ (unsigned long long)ino, index, rec->e_flags, cpos);
+ goto out;
+ }
+
/*
* after moving/defraging to new location, the extent is not going
* to be refcounted anymore.
--
2.51.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH 2/2] ocfs2: relax BUG() to ocfs2_error() in __ocfs2_move_extent()
2025-10-09 10:23 ` [PATCH 2/2] ocfs2: relax BUG() to ocfs2_error() in __ocfs2_move_extent() Dmitry Antipov
@ 2025-10-09 11:12 ` Joseph Qi
2025-11-12 8:30 ` Andy Shevchenko
0 siblings, 1 reply; 11+ messages in thread
From: Joseph Qi @ 2025-10-09 11:12 UTC (permalink / raw)
To: Dmitry Antipov, Mark Fasheh, Joel Becker, akpm
Cc: ocfs2-devel, lvc-project, syzbot+727d161855d11d81e411
On 2025/10/9 18:23, Dmitry Antipov wrote:
> In '__ocfs2_move_extent()', relax 'BUG()' to 'ocfs2_error()' just
> to avoid crashing the whole kernel due to a filesystem corruption.
>
> Reported-by: syzbot+727d161855d11d81e411@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=727d161855d11d81e411
> Fixes: 8f603e567aa7 ("Ocfs2/move_extents: move a range of extent.")
> Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
Looks fine.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/move_extents.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c
> index e038c009cdef..ba4952b41602 100644
> --- a/fs/ocfs2/move_extents.c
> +++ b/fs/ocfs2/move_extents.c
> @@ -98,7 +98,13 @@ static int __ocfs2_move_extent(handle_t *handle,
>
> rec = &el->l_recs[index];
>
> - BUG_ON(ext_flags != rec->e_flags);
> + if (ext_flags != rec->e_flags) {
> + ret = ocfs2_error(inode->i_sb,
> + "Inode %llu has corrupted extent %d with flags 0x%x at cpos %u\n",
> + (unsigned long long)ino, index, rec->e_flags, cpos);
> + goto out;
> + }
> +
> /*
> * after moving/defraging to new location, the extent is not going
> * to be refcounted anymore.
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH 2/2] ocfs2: relax BUG() to ocfs2_error() in __ocfs2_move_extent()
2025-10-09 11:12 ` Joseph Qi
@ 2025-11-12 8:30 ` Andy Shevchenko
2025-11-12 18:02 ` Andrew Morton
0 siblings, 1 reply; 11+ messages in thread
From: Andy Shevchenko @ 2025-11-12 8:30 UTC (permalink / raw)
To: Joseph Qi, Andrew Morton
Cc: Dmitry Antipov, Mark Fasheh, Joel Becker, ocfs2-devel,
lvc-project, syzbot+727d161855d11d81e411
On Thu, Oct 09, 2025 at 07:12:15PM +0800, Joseph Qi wrote:
> On 2025/10/9 18:23, Dmitry Antipov wrote:
> > Reported-by: syzbot+727d161855d11d81e411@syzkaller.appspotmail.com
> > Closes: https://syzkaller.appspot.com/bug?extid=727d161855d11d81e411
> > Fixes: 8f603e567aa7 ("Ocfs2/move_extents: move a range of extent.")
> > Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
Andrew, something wrong went into the repository. If you look at
https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git/commit/?h=mm-nonmm-stable&id=63b0c2c8cd29f0b516bbe6bb6580ed1b0246996c
looks like a one off case, as others seem okay in the repo. I can't see any
suspicious pattern in the tags, but it may be a very subtle bugs in the scripts
you are using.
(As of today the old version in the Linux Next df3de4b76ba17f9 has the same issue).
...
So, the problem is that two tags are coupled together:
Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>Closes: https://syzkaller.appspot.com/bug?extid=727d161855d
11d81e411
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH 2/2] ocfs2: relax BUG() to ocfs2_error() in __ocfs2_move_extent()
2025-11-12 8:30 ` Andy Shevchenko
@ 2025-11-12 18:02 ` Andrew Morton
0 siblings, 0 replies; 11+ messages in thread
From: Andrew Morton @ 2025-11-12 18:02 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Joseph Qi, Dmitry Antipov, Mark Fasheh, Joel Becker, ocfs2-devel,
lvc-project, syzbot+727d161855d11d81e411
On Wed, 12 Nov 2025 09:30:44 +0100 Andy Shevchenko <andriy.shevchenko@intel.com> wrote:
> On Thu, Oct 09, 2025 at 07:12:15PM +0800, Joseph Qi wrote:
> > On 2025/10/9 18:23, Dmitry Antipov wrote:
>
> > > Reported-by: syzbot+727d161855d11d81e411@syzkaller.appspotmail.com
> > > Closes: https://syzkaller.appspot.com/bug?extid=727d161855d11d81e411
> > > Fixes: 8f603e567aa7 ("Ocfs2/move_extents: move a range of extent.")
> > > Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
>
> Andrew, something wrong went into the repository. If you look at
> https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git/commit/?h=mm-nonmm-stable&id=63b0c2c8cd29f0b516bbe6bb6580ed1b0246996c
>
> looks like a one off case, as others seem okay in the repo. I can't see any
> suspicious pattern in the tags,
doh, thanks, fixed.
> but it may be a very subtle bugs in the scripts
> you are using.
I do quite a bit of stuff manually - there's so little consistency in
what I receive that scripting more than I do would be a nightmare.
Plus there's benefit in actually looking at things.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/2] ocfs2: add extra flags check in ocfs2_ioctl_move_extents()
2025-10-09 10:23 ` [PATCH 1/2] " Dmitry Antipov
2025-10-09 10:23 ` [PATCH 2/2] ocfs2: relax BUG() to ocfs2_error() in __ocfs2_move_extent() Dmitry Antipov
@ 2025-10-09 11:07 ` Joseph Qi
1 sibling, 0 replies; 11+ messages in thread
From: Joseph Qi @ 2025-10-09 11:07 UTC (permalink / raw)
To: Dmitry Antipov, Mark Fasheh, Joel Becker, akpm; +Cc: ocfs2-devel, lvc-project
On 2025/10/9 18:23, Dmitry Antipov wrote:
> In 'ocfs2_ioctl_move_extents()', add extra check whether only actually
> supported flags are passed via 'ioctl(..., OCFS2_IOC_MOVE_EXT, ...)',
> and reject anything beyond OCFS2_MOVE_EXT_FL_AUTO_DEFRAG and
> OCFS2_MOVE_EXT_FL_PART_DEFRAG with -EINVAL. In particular,
> OCFS2_MOVE_EXT_FL_COMPLETE may be set by the kernel only and
> should never be passed from userspace.
>
> Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
Looks fine.
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
> ---
> fs/ocfs2/move_extents.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c
> index 86f2631e6360..e038c009cdef 100644
> --- a/fs/ocfs2/move_extents.c
> +++ b/fs/ocfs2/move_extents.c
> @@ -1031,6 +1031,12 @@ int ocfs2_ioctl_move_extents(struct file *filp, void __user *argp)
> if (range.me_threshold > i_size_read(inode))
> range.me_threshold = i_size_read(inode);
>
> + if (range.me_flags & ~(OCFS2_MOVE_EXT_FL_AUTO_DEFRAG |
> + OCFS2_MOVE_EXT_FL_PART_DEFRAG)) {
> + status = -EINVAL;
> + goto out_free;
> + }
> +
> if (range.me_flags & OCFS2_MOVE_EXT_FL_AUTO_DEFRAG) {
> context->auto_defrag = 1;
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] ocfs2: add extra flags check in ocfs2_ioctl_move_extents()
2025-10-09 7:51 ` Joseph Qi
2025-10-09 10:23 ` [PATCH 1/2] " Dmitry Antipov
@ 2025-10-09 10:25 ` Dmitry Antipov
1 sibling, 0 replies; 11+ messages in thread
From: Dmitry Antipov @ 2025-10-09 10:25 UTC (permalink / raw)
To: Joseph Qi, Mark Fasheh, Joel Becker
Cc: ocfs2-devel, lvc-project, syzbot+727d161855d11d81e411
On 10/9/25 10:51 AM, Joseph Qi wrote:
> So you mean the reproducer passes OCFS2_MOVE_EXT_FL_COMPLETE through
> ioctl and then trigger this BUG?
Looking from the kernel side, the reproducer has passed
ocfs2_ioctl_move_extents({ .range.me_flags = 0x0; }) once,
and next call to ocfs2_ioctl_move_extents({ .range.me_flags = 0x4; })
has triggered the BUG() actually.
> This looks more sane and seems directly fix the BUG.
> BTW, we'd better also log the extent flags.
If so, the whole thing has to be split into two patches:
1) reject invalid flags in ocfs2_ioctl_move_extents();
2) in __ocfs2_move_extent(), relax BUG() to ocfs2_error().
Dmitry
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2025-11-12 18:02 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-08 11:20 [PATCH] ocfs2: add extra flags check in ocfs2_ioctl_move_extents() Dmitry Antipov
2025-10-09 2:15 ` Joseph Qi
2025-10-09 6:39 ` Dmitry Antipov
2025-10-09 7:51 ` Joseph Qi
2025-10-09 10:23 ` [PATCH 1/2] " Dmitry Antipov
2025-10-09 10:23 ` [PATCH 2/2] ocfs2: relax BUG() to ocfs2_error() in __ocfs2_move_extent() Dmitry Antipov
2025-10-09 11:12 ` Joseph Qi
2025-11-12 8:30 ` Andy Shevchenko
2025-11-12 18:02 ` Andrew Morton
2025-10-09 11:07 ` [PATCH 1/2] ocfs2: add extra flags check in ocfs2_ioctl_move_extents() Joseph Qi
2025-10-09 10:25 ` [PATCH] " Dmitry Antipov
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.