All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] xfs: fix uaf when leaf dir bestcount not match with dir data blocks
@ 2022-08-31 12:16 Guo Xuenan
  2022-09-12  1:31 ` Dave Chinner
  0 siblings, 1 reply; 9+ messages in thread
From: Guo Xuenan @ 2022-08-31 12:16 UTC (permalink / raw)
  To: linux-xfs, djwong, dchinner
  Cc: chandan.babu, yi.zhang, houtao1, zhengbin13, jack.qiu, guoxuenan

For leaf dir, In most cases, there should be as many bestfree slots
as the dir data blocks that can fit under i_size (except for [1]).

Root cause is we don't examin the number bestfree slots, when the slots
number less than dir data blocks, if we need to allocate new dir data
block and update the bestfree array, we will use the dir block number as
index to assign bestfree array, while we did not check the leaf buf
boundary which may cause UAF or other memory access problem. This issue
can also triggered with test cases xfs/473 from fstests.

Considering the special case [1] , only add check bestfree array boundary,
to avoid UAF or slab-out-of bound.

[1] https://lore.kernel.org/all/163961697197.3129691.1911552605195534271.stgit@magnolia/

Simplify the testcase xfs/473 with commands below:
DEV=/dev/sdb
MP=/mnt/sdb
WORKDIR=/mnt/sdb/341 #1. mkfs create new xfs image
mkfs.xfs -f ${DEV}
mount ${DEV} ${MP}
mkdir -p ${WORKDIR}
for i in `seq 1 341` #2. create leaf dir with 341 entries file name len 8
do
    touch ${WORKDIR}/$(printf "%08d" ${i})
done
inode=$(ls -i ${MP} | cut -d' ' -f1)
umount ${MP}         #3. xfs_db set bestcount to 0
xfs_db -x ${DEV} -c "inode ${inode}" -c "dblock 8388608" \
-c "write ltail.bestcount 0"
mount ${DEV} ${MP}
touch ${WORKDIR}/{1..100}.txt #4. touch new file, reproduce

The error log is shown as follows:
==================================================================
BUG: KASAN: use-after-free in xfs_dir2_leaf_addname+0x1995/0x1ac0
Write of size 2 at addr ffff88810168b000 by task touch/1552
CPU: 5 PID: 1552 Comm: touch Not tainted 6.0.0-rc3+ #101
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.13.0-1ubuntu1.1 04/01/2014
Call Trace:
 <TASK>
 dump_stack_lvl+0x4d/0x66
 print_report.cold+0xf6/0x691
 kasan_report+0xa8/0x120
 xfs_dir2_leaf_addname+0x1995/0x1ac0
 xfs_dir_createname+0x58c/0x7f0
 xfs_create+0x7af/0x1010
 xfs_generic_create+0x270/0x5e0
 path_openat+0x270b/0x3450
 do_filp_open+0x1cf/0x2b0
 do_sys_openat2+0x46b/0x7a0
 do_sys_open+0xb7/0x130
 do_syscall_64+0x35/0x80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x7fe4d9e9312b
Code: 25 00 00 41 00 3d 00 00 41 00 74 4b 64 8b 04 25 18 00 00 00 85 c0
75 67 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00
f0 ff ff 0f 87 91 00 00 00 48 8b 4c 24 28 64 48 33 0c 25
RSP: 002b:00007ffda4c16c20 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fe4d9e9312b
RDX: 0000000000000941 RSI: 00007ffda4c17f33 RDI: 00000000ffffff9c
RBP: 00007ffda4c17f33 R08: 0000000000000000 R09: 0000000000000000
R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000941
R13: 00007fe4d9f631a4 R14: 00007ffda4c17f33 R15: 0000000000000000
 </TASK>

The buggy address belongs to the physical page:
page:ffffea000405a2c0 refcount:0 mapcount:0 mapping:0000000000000000
index:0x0 pfn:0x10168b
flags: 0x2fffff80000000(node=0|zone=2|lastcpupid=0x1fffff)
raw: 002fffff80000000 ffffea0004057788 ffffea000402dbc8 0000000000000000
raw: 0000000000000000 0000000000170000 00000000ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff88810168af00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ffff88810168af80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffff88810168b000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
                   ^
 ffff88810168b080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 ffff88810168b100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
==================================================================
Disabling lock debugging due to kernel taint
00000000: 58 44 44 33 5b 53 35 c2 00 00 00 00 00 00 00 78
XDD3[S5........x
XFS (sdb): Internal error xfs_dir2_data_use_free at line 1200 of file
fs/xfs/libxfs/xfs_dir2_data.c.  Caller
xfs_dir2_data_use_free+0x28a/0xeb0
CPU: 5 PID: 1552 Comm: touch Tainted: G    B              6.0.0-rc3+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.13.0-1ubuntu1.1 04/01/2014
Call Trace:
 <TASK>
 dump_stack_lvl+0x4d/0x66
 xfs_corruption_error+0x132/0x150
 xfs_dir2_data_use_free+0x198/0xeb0
 xfs_dir2_leaf_addname+0xa59/0x1ac0
 xfs_dir_createname+0x58c/0x7f0
 xfs_create+0x7af/0x1010
 xfs_generic_create+0x270/0x5e0
 path_openat+0x270b/0x3450
 do_filp_open+0x1cf/0x2b0
 do_sys_openat2+0x46b/0x7a0
 do_sys_open+0xb7/0x130
 do_syscall_64+0x35/0x80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x7fe4d9e9312b
Code: 25 00 00 41 00 3d 00 00 41 00 74 4b 64 8b 04 25 18 00 00 00 85 c0
75 67 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00
f0 ff ff 0f 87 91 00 00 00 48 8b 4c 24 28 64 48 33 0c 25
RSP: 002b:00007ffda4c16c20 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fe4d9e9312b
RDX: 0000000000000941 RSI: 00007ffda4c17f46 RDI: 00000000ffffff9c
RBP: 00007ffda4c17f46 R08: 0000000000000000 R09: 0000000000000001
R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000941
R13: 00007fe4d9f631a4 R14: 00007ffda4c17f46 R15: 0000000000000000
 </TASK>
XFS (sdb): Corruption detected. Unmount and run xfs_repair

Signed-off-by: Guo Xuenan <guoxuenan@huawei.com>
Reviewed-by: Hou Tao <houtao1@huawei.com>
---
 fs/xfs/libxfs/xfs_dir2_leaf.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index d9b66306a9a7..4b2a72b3a6f3 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -819,6 +819,18 @@ xfs_dir2_leaf_addname(
 		 */
 		else
 			xfs_dir3_leaf_log_bests(args, lbp, use_block, use_block);
+		/*
+		 * An abnormal corner case, bestfree count less than data
+		 * blocks, add a condition to avoid UAF or slab-out-of bound.
+		 */
+		if ((char *)(&bestsp[use_block]) > (char *)ltp) {
+			xfs_trans_brelse(tp, lbp);
+			if (tp->t_flags & XFS_TRANS_DIRTY)
+				xfs_force_shutdown(tp->t_mountp,
+						SHUTDOWN_CORRUPT_ONDISK);
+			return -EFSCORRUPTED;
+		}
+
 		hdr = dbp->b_addr;
 		bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr);
 		bestsp[use_block] = bf[0].length;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] xfs: fix uaf when leaf dir bestcount not match with dir data blocks
  2022-08-31 12:16 [PATCH v2] xfs: fix uaf when leaf dir bestcount not match with dir data blocks Guo Xuenan
@ 2022-09-12  1:31 ` Dave Chinner
  2022-09-14 16:30   ` Darrick J. Wong
                     ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Dave Chinner @ 2022-09-12  1:31 UTC (permalink / raw)
  To: Guo Xuenan
  Cc: linux-xfs, djwong, dchinner, chandan.babu, yi.zhang, houtao1,
	zhengbin13, jack.qiu

On Wed, Aug 31, 2022 at 08:16:39PM +0800, Guo Xuenan wrote:
> For leaf dir, In most cases, there should be as many bestfree slots
> as the dir data blocks that can fit under i_size (except for [1]).
> 
> Root cause is we don't examin the number bestfree slots, when the slots
> number less than dir data blocks, if we need to allocate new dir data
> block and update the bestfree array, we will use the dir block number as
> index to assign bestfree array, while we did not check the leaf buf
> boundary which may cause UAF or other memory access problem. This issue
> can also triggered with test cases xfs/473 from fstests.
> 
> Considering the special case [1] , only add check bestfree array boundary,
> to avoid UAF or slab-out-of bound.
> 
> [1] https://lore.kernel.org/all/163961697197.3129691.1911552605195534271.stgit@magnolia/
> 
> Simplify the testcase xfs/473 with commands below:
> DEV=/dev/sdb
> MP=/mnt/sdb
> WORKDIR=/mnt/sdb/341 #1. mkfs create new xfs image
> mkfs.xfs -f ${DEV}
> mount ${DEV} ${MP}
> mkdir -p ${WORKDIR}
> for i in `seq 1 341` #2. create leaf dir with 341 entries file name len 8
> do
>     touch ${WORKDIR}/$(printf "%08d" ${i})
> done
> inode=$(ls -i ${MP} | cut -d' ' -f1)
> umount ${MP}         #3. xfs_db set bestcount to 0
> xfs_db -x ${DEV} -c "inode ${inode}" -c "dblock 8388608" \
> -c "write ltail.bestcount 0"
> mount ${DEV} ${MP}
> touch ${WORKDIR}/{1..100}.txt #4. touch new file, reproduce
.....
> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> index d9b66306a9a7..4b2a72b3a6f3 100644
> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> @@ -819,6 +819,18 @@ xfs_dir2_leaf_addname(
>  		 */
>  		else
>  			xfs_dir3_leaf_log_bests(args, lbp, use_block, use_block);
> +		/*
> +		 * An abnormal corner case, bestfree count less than data
> +		 * blocks, add a condition to avoid UAF or slab-out-of bound.
> +		 */
> +		if ((char *)(&bestsp[use_block]) > (char *)ltp) {
> +			xfs_trans_brelse(tp, lbp);
> +			if (tp->t_flags & XFS_TRANS_DIRTY)
> +				xfs_force_shutdown(tp->t_mountp,
> +						SHUTDOWN_CORRUPT_ONDISK);
> +			return -EFSCORRUPTED;
> +		}
> +

As I explained here:

https://lore.kernel.org/linux-xfs/20220829081244.GT3600936@dread.disaster.area/

We don't check for overruns caused by on-disk format corruptions in
every operation - we catch the corruption when the metadata is first
read into memory via the verifier.

Please add a check for a corrupt/mismatched best sizes array to
xfs_dir3_leaf_check_int() so that the corruption is detected on
first read and the internal directory code is never exposed to such
issues.

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] xfs: fix uaf when leaf dir bestcount not match with dir data blocks
  2022-09-12  1:31 ` Dave Chinner
@ 2022-09-14 16:30   ` Darrick J. Wong
  2022-09-28 10:06   ` [PATCH v3] xfs: fix expection caused by unexpected illegal bestcount in leaf dir Guo Xuenan
  2022-09-29  8:51   ` [PATCH v4] xfs: fix exception " Guo Xuenan
  2 siblings, 0 replies; 9+ messages in thread
From: Darrick J. Wong @ 2022-09-14 16:30 UTC (permalink / raw)
  To: Dave Chinner
  Cc: Guo Xuenan, linux-xfs, dchinner, chandan.babu, yi.zhang, houtao1,
	zhengbin13, jack.qiu

On Mon, Sep 12, 2022 at 11:31:54AM +1000, Dave Chinner wrote:
> On Wed, Aug 31, 2022 at 08:16:39PM +0800, Guo Xuenan wrote:
> > For leaf dir, In most cases, there should be as many bestfree slots
> > as the dir data blocks that can fit under i_size (except for [1]).
> > 
> > Root cause is we don't examin the number bestfree slots, when the slots
> > number less than dir data blocks, if we need to allocate new dir data
> > block and update the bestfree array, we will use the dir block number as
> > index to assign bestfree array, while we did not check the leaf buf
> > boundary which may cause UAF or other memory access problem. This issue
> > can also triggered with test cases xfs/473 from fstests.
> > 
> > Considering the special case [1] , only add check bestfree array boundary,
> > to avoid UAF or slab-out-of bound.
> > 
> > [1] https://lore.kernel.org/all/163961697197.3129691.1911552605195534271.stgit@magnolia/
> > 
> > Simplify the testcase xfs/473 with commands below:
> > DEV=/dev/sdb
> > MP=/mnt/sdb
> > WORKDIR=/mnt/sdb/341 #1. mkfs create new xfs image
> > mkfs.xfs -f ${DEV}
> > mount ${DEV} ${MP}
> > mkdir -p ${WORKDIR}
> > for i in `seq 1 341` #2. create leaf dir with 341 entries file name len 8
> > do
> >     touch ${WORKDIR}/$(printf "%08d" ${i})
> > done
> > inode=$(ls -i ${MP} | cut -d' ' -f1)
> > umount ${MP}         #3. xfs_db set bestcount to 0
> > xfs_db -x ${DEV} -c "inode ${inode}" -c "dblock 8388608" \
> > -c "write ltail.bestcount 0"
> > mount ${DEV} ${MP}
> > touch ${WORKDIR}/{1..100}.txt #4. touch new file, reproduce
> .....
> > diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> > index d9b66306a9a7..4b2a72b3a6f3 100644
> > --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> > +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> > @@ -819,6 +819,18 @@ xfs_dir2_leaf_addname(
> >  		 */
> >  		else
> >  			xfs_dir3_leaf_log_bests(args, lbp, use_block, use_block);
> > +		/*
> > +		 * An abnormal corner case, bestfree count less than data
> > +		 * blocks, add a condition to avoid UAF or slab-out-of bound.
> > +		 */
> > +		if ((char *)(&bestsp[use_block]) > (char *)ltp) {

Aha, so this /can/ be detected by walking off the end of the buffer...

> > +			xfs_trans_brelse(tp, lbp);
> > +			if (tp->t_flags & XFS_TRANS_DIRTY)
> > +				xfs_force_shutdown(tp->t_mountp,
> > +						SHUTDOWN_CORRUPT_ONDISK);
> > +			return -EFSCORRUPTED;
> > +		}
> > +
> 
> As I explained here:
> 
> https://lore.kernel.org/linux-xfs/20220829081244.GT3600936@dread.disaster.area/
> 
> We don't check for overruns caused by on-disk format corruptions in
> every operation - we catch the corruption when the metadata is first
> read into memory via the verifier.
> 
> Please add a check for a corrupt/mismatched best sizes array to
> xfs_dir3_leaf_check_int() so that the corruption is detected on
> first read and the internal directory code is never exposed to such
> issues.

...in which case this should go in the buffer verifier.  Seconded.

--D

> 
> Cheers,
> 
> Dave.
> -- 
> Dave Chinner
> david@fromorbit.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3] xfs: fix expection caused by unexpected illegal bestcount in leaf dir
  2022-09-12  1:31 ` Dave Chinner
  2022-09-14 16:30   ` Darrick J. Wong
@ 2022-09-28 10:06   ` Guo Xuenan
  2022-09-29  8:51   ` [PATCH v4] xfs: fix exception " Guo Xuenan
  2 siblings, 0 replies; 9+ messages in thread
From: Guo Xuenan @ 2022-09-28 10:06 UTC (permalink / raw)
  To: david, dchinner
  Cc: chandan.babu, djwong, guoxuenan, houtao1, jack.qiu, linux-xfs,
	yi.zhang, zhengbin13

For leaf dir, In most cases, there should be as many bestfree slots
as the dir data blocks that can fit under i_size (except for [1]).

Root cause is we don't examin the number bestfree slots, when the slots
number less than dir data blocks, if we need to allocate new dir data
block and update the bestfree array, we will use the dir block number as
index to assign bestfree array, while we did not check the leaf buf
boundary which may cause UAF or other memory access problem. This issue
can also triggered with test cases xfs/473 from fstests.

According to Dave Chinner & Darrick's suggestion, adding buffer verifier
to detect this abnormal situation in time.
Simplify the testcase for fstest xfs/554 [1]

The error log is shown as follows:
==================================================================
BUG: KASAN: use-after-free in xfs_dir2_leaf_addname+0x1995/0x1ac0
Write of size 2 at addr ffff88810168b000 by task touch/1552
CPU: 5 PID: 1552 Comm: touch Not tainted 6.0.0-rc3+ #101
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.13.0-1ubuntu1.1 04/01/2014
Call Trace:
 <TASK>
 dump_stack_lvl+0x4d/0x66
 print_report.cold+0xf6/0x691
 kasan_report+0xa8/0x120
 xfs_dir2_leaf_addname+0x1995/0x1ac0
 xfs_dir_createname+0x58c/0x7f0
 xfs_create+0x7af/0x1010
 xfs_generic_create+0x270/0x5e0
 path_openat+0x270b/0x3450
 do_filp_open+0x1cf/0x2b0
 do_sys_openat2+0x46b/0x7a0
 do_sys_open+0xb7/0x130
 do_syscall_64+0x35/0x80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x7fe4d9e9312b
Code: 25 00 00 41 00 3d 00 00 41 00 74 4b 64 8b 04 25 18 00 00 00 85 c0
75 67 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00
f0 ff ff 0f 87 91 00 00 00 48 8b 4c 24 28 64 48 33 0c 25
RSP: 002b:00007ffda4c16c20 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fe4d9e9312b
RDX: 0000000000000941 RSI: 00007ffda4c17f33 RDI: 00000000ffffff9c
RBP: 00007ffda4c17f33 R08: 0000000000000000 R09: 0000000000000000
R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000941
R13: 00007fe4d9f631a4 R14: 00007ffda4c17f33 R15: 0000000000000000
 </TASK>

The buggy address belongs to the physical page:
page:ffffea000405a2c0 refcount:0 mapcount:0 mapping:0000000000000000
index:0x0 pfn:0x10168b
flags: 0x2fffff80000000(node=0|zone=2|lastcpupid=0x1fffff)
raw: 002fffff80000000 ffffea0004057788 ffffea000402dbc8 0000000000000000
raw: 0000000000000000 0000000000170000 00000000ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff88810168af00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ffff88810168af80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffff88810168b000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
                   ^
 ffff88810168b080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 ffff88810168b100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
==================================================================
Disabling lock debugging due to kernel taint
00000000: 58 44 44 33 5b 53 35 c2 00 00 00 00 00 00 00 78
XDD3[S5........x
XFS (sdb): Internal error xfs_dir2_data_use_free at line 1200 of file
fs/xfs/libxfs/xfs_dir2_data.c.  Caller
xfs_dir2_data_use_free+0x28a/0xeb0
CPU: 5 PID: 1552 Comm: touch Tainted: G    B              6.0.0-rc3+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.13.0-1ubuntu1.1 04/01/2014
Call Trace:
 <TASK>
 dump_stack_lvl+0x4d/0x66
 xfs_corruption_error+0x132/0x150
 xfs_dir2_data_use_free+0x198/0xeb0
 xfs_dir2_leaf_addname+0xa59/0x1ac0
 xfs_dir_createname+0x58c/0x7f0
 xfs_create+0x7af/0x1010
 xfs_generic_create+0x270/0x5e0
 path_openat+0x270b/0x3450
 do_filp_open+0x1cf/0x2b0
 do_sys_openat2+0x46b/0x7a0
 do_sys_open+0xb7/0x130
 do_syscall_64+0x35/0x80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x7fe4d9e9312b
Code: 25 00 00 41 00 3d 00 00 41 00 74 4b 64 8b 04 25 18 00 00 00 85 c0
75 67 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00
f0 ff ff 0f 87 91 00 00 00 48 8b 4c 24 28 64 48 33 0c 25
RSP: 002b:00007ffda4c16c20 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fe4d9e9312b
RDX: 0000000000000941 RSI: 00007ffda4c17f46 RDI: 00000000ffffff9c
RBP: 00007ffda4c17f46 R08: 0000000000000000 R09: 0000000000000001
R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000941
R13: 00007fe4d9f631a4 R14: 00007ffda4c17f46 R15: 0000000000000000
 </TASK>
XFS (sdb): Corruption detected. Unmount and run xfs_repair

[1] https://lore.kernel.org/all/20220928095355.2074025-1-guoxuenan@huawei.com/
Reviewed-by: Hou Tao <houtao1@huawei.com>
Signed-off-by: Guo Xuenan <guoxuenan@huawei.com>
---
 fs/xfs/libxfs/xfs_dir2_leaf.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index d9b66306a9a7..482fc441ac99 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -146,6 +146,7 @@ xfs_dir3_leaf_check_int(
 	xfs_dir2_leaf_tail_t		*ltp;
 	int				stale;
 	int				i;
+	xfs_dir2_db_t 			db;
 
 	ltp = xfs_dir2_leaf_tail_p(geo, leaf);
 
@@ -175,6 +176,9 @@ xfs_dir3_leaf_check_int(
 		}
 		if (hdr->ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
 			stale++;
+		db = xfs_dir2_dataptr_to_db(geo, be32_to_cpu(hdr->ents[i].address));
+		if (db >= be32_to_cpu(ltp->bestcount))
+			return __this_address;
 	}
 	if (hdr->stale != stale)
 		return __this_address;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v4] xfs: fix exception caused by unexpected illegal bestcount in leaf dir
  2022-09-12  1:31 ` Dave Chinner
  2022-09-14 16:30   ` Darrick J. Wong
  2022-09-28 10:06   ` [PATCH v3] xfs: fix expection caused by unexpected illegal bestcount in leaf dir Guo Xuenan
@ 2022-09-29  8:51   ` Guo Xuenan
  2022-09-29 20:50     ` Darrick J. Wong
  2 siblings, 1 reply; 9+ messages in thread
From: Guo Xuenan @ 2022-09-29  8:51 UTC (permalink / raw)
  To: david, dchinner
  Cc: chandan.babu, djwong, guoxuenan, houtao1, jack.qiu, linux-xfs,
	yi.zhang, zhengbin13

For leaf dir, In most cases, there should be as many bestfree slots
as the dir data blocks that can fit under i_size (except for [1]).

Root cause is we don't examin the number bestfree slots, when the slots
number less than dir data blocks, if we need to allocate new dir data
block and update the bestfree array, we will use the dir block number as
index to assign bestfree array, while we did not check the leaf buf
boundary which may cause UAF or other memory access problem. This issue
can also triggered with test cases xfs/473 from fstests.

According to Dave Chinner & Darrick's suggestion, adding buffer verifier
to detect this abnormal situation in time.
Simplify the testcase for fstest xfs/554 [1]

The error log is shown as follows:
==================================================================
BUG: KASAN: use-after-free in xfs_dir2_leaf_addname+0x1995/0x1ac0
Write of size 2 at addr ffff88810168b000 by task touch/1552
CPU: 5 PID: 1552 Comm: touch Not tainted 6.0.0-rc3+ #101
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.13.0-1ubuntu1.1 04/01/2014
Call Trace:
 <TASK>
 dump_stack_lvl+0x4d/0x66
 print_report.cold+0xf6/0x691
 kasan_report+0xa8/0x120
 xfs_dir2_leaf_addname+0x1995/0x1ac0
 xfs_dir_createname+0x58c/0x7f0
 xfs_create+0x7af/0x1010
 xfs_generic_create+0x270/0x5e0
 path_openat+0x270b/0x3450
 do_filp_open+0x1cf/0x2b0
 do_sys_openat2+0x46b/0x7a0
 do_sys_open+0xb7/0x130
 do_syscall_64+0x35/0x80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x7fe4d9e9312b
Code: 25 00 00 41 00 3d 00 00 41 00 74 4b 64 8b 04 25 18 00 00 00 85 c0
75 67 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00
f0 ff ff 0f 87 91 00 00 00 48 8b 4c 24 28 64 48 33 0c 25
RSP: 002b:00007ffda4c16c20 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fe4d9e9312b
RDX: 0000000000000941 RSI: 00007ffda4c17f33 RDI: 00000000ffffff9c
RBP: 00007ffda4c17f33 R08: 0000000000000000 R09: 0000000000000000
R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000941
R13: 00007fe4d9f631a4 R14: 00007ffda4c17f33 R15: 0000000000000000
 </TASK>

The buggy address belongs to the physical page:
page:ffffea000405a2c0 refcount:0 mapcount:0 mapping:0000000000000000
index:0x0 pfn:0x10168b
flags: 0x2fffff80000000(node=0|zone=2|lastcpupid=0x1fffff)
raw: 002fffff80000000 ffffea0004057788 ffffea000402dbc8 0000000000000000
raw: 0000000000000000 0000000000170000 00000000ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff88810168af00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ffff88810168af80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffff88810168b000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
                   ^
 ffff88810168b080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 ffff88810168b100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
==================================================================
Disabling lock debugging due to kernel taint
00000000: 58 44 44 33 5b 53 35 c2 00 00 00 00 00 00 00 78
XDD3[S5........x
XFS (sdb): Internal error xfs_dir2_data_use_free at line 1200 of file
fs/xfs/libxfs/xfs_dir2_data.c.  Caller
xfs_dir2_data_use_free+0x28a/0xeb0
CPU: 5 PID: 1552 Comm: touch Tainted: G    B              6.0.0-rc3+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.13.0-1ubuntu1.1 04/01/2014
Call Trace:
 <TASK>
 dump_stack_lvl+0x4d/0x66
 xfs_corruption_error+0x132/0x150
 xfs_dir2_data_use_free+0x198/0xeb0
 xfs_dir2_leaf_addname+0xa59/0x1ac0
 xfs_dir_createname+0x58c/0x7f0
 xfs_create+0x7af/0x1010
 xfs_generic_create+0x270/0x5e0
 path_openat+0x270b/0x3450
 do_filp_open+0x1cf/0x2b0
 do_sys_openat2+0x46b/0x7a0
 do_sys_open+0xb7/0x130
 do_syscall_64+0x35/0x80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x7fe4d9e9312b
Code: 25 00 00 41 00 3d 00 00 41 00 74 4b 64 8b 04 25 18 00 00 00 85 c0
75 67 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00
f0 ff ff 0f 87 91 00 00 00 48 8b 4c 24 28 64 48 33 0c 25
RSP: 002b:00007ffda4c16c20 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fe4d9e9312b
RDX: 0000000000000941 RSI: 00007ffda4c17f46 RDI: 00000000ffffff9c
RBP: 00007ffda4c17f46 R08: 0000000000000000 R09: 0000000000000001
R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000941
R13: 00007fe4d9f631a4 R14: 00007ffda4c17f46 R15: 0000000000000000
 </TASK>
XFS (sdb): Corruption detected. Unmount and run xfs_repair

[1] https://lore.kernel.org/all/20220928095355.2074025-1-guoxuenan@huawei.com/
Reviewed-by: Hou Tao <houtao1@huawei.com>
Signed-off-by: Guo Xuenan <guoxuenan@huawei.com>
---
 fs/xfs/libxfs/xfs_dir2_leaf.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index d9b66306a9a7..bf4633b228cd 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -146,6 +146,7 @@ xfs_dir3_leaf_check_int(
 	xfs_dir2_leaf_tail_t		*ltp;
 	int				stale;
 	int				i;
+	xfs_dir2_db_t			db;
 
 	ltp = xfs_dir2_leaf_tail_p(geo, leaf);
 
@@ -175,6 +176,9 @@ xfs_dir3_leaf_check_int(
 		}
 		if (hdr->ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
 			stale++;
+		db = xfs_dir2_dataptr_to_db(geo, be32_to_cpu(hdr->ents[i].address));
+		if (db >= be32_to_cpu(ltp->bestcount))
+			return __this_address;
 	}
 	if (hdr->stale != stale)
 		return __this_address;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v4] xfs: fix exception caused by unexpected illegal bestcount in leaf dir
  2022-09-29  8:51   ` [PATCH v4] xfs: fix exception " Guo Xuenan
@ 2022-09-29 20:50     ` Darrick J. Wong
  2022-10-07 11:33       ` Guo Xuenan
  0 siblings, 1 reply; 9+ messages in thread
From: Darrick J. Wong @ 2022-09-29 20:50 UTC (permalink / raw)
  To: Guo Xuenan
  Cc: david, dchinner, chandan.babu, houtao1, jack.qiu, linux-xfs,
	yi.zhang, zhengbin13

On Thu, Sep 29, 2022 at 04:51:55PM +0800, Guo Xuenan wrote:
> For leaf dir, In most cases, there should be as many bestfree slots
> as the dir data blocks that can fit under i_size (except for [1]).
> 
> Root cause is we don't examin the number bestfree slots, when the slots
> number less than dir data blocks, if we need to allocate new dir data
> block and update the bestfree array, we will use the dir block number as
> index to assign bestfree array, while we did not check the leaf buf
> boundary which may cause UAF or other memory access problem. This issue
> can also triggered with test cases xfs/473 from fstests.
> 
> According to Dave Chinner & Darrick's suggestion, adding buffer verifier
> to detect this abnormal situation in time.
> Simplify the testcase for fstest xfs/554 [1]
> 
> The error log is shown as follows:
> ==================================================================
> BUG: KASAN: use-after-free in xfs_dir2_leaf_addname+0x1995/0x1ac0
> Write of size 2 at addr ffff88810168b000 by task touch/1552
> CPU: 5 PID: 1552 Comm: touch Not tainted 6.0.0-rc3+ #101
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
> 1.13.0-1ubuntu1.1 04/01/2014
> Call Trace:
>  <TASK>
>  dump_stack_lvl+0x4d/0x66
>  print_report.cold+0xf6/0x691
>  kasan_report+0xa8/0x120
>  xfs_dir2_leaf_addname+0x1995/0x1ac0
>  xfs_dir_createname+0x58c/0x7f0
>  xfs_create+0x7af/0x1010
>  xfs_generic_create+0x270/0x5e0
>  path_openat+0x270b/0x3450
>  do_filp_open+0x1cf/0x2b0
>  do_sys_openat2+0x46b/0x7a0
>  do_sys_open+0xb7/0x130
>  do_syscall_64+0x35/0x80
>  entry_SYSCALL_64_after_hwframe+0x63/0xcd
> RIP: 0033:0x7fe4d9e9312b
> Code: 25 00 00 41 00 3d 00 00 41 00 74 4b 64 8b 04 25 18 00 00 00 85 c0
> 75 67 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00
> f0 ff ff 0f 87 91 00 00 00 48 8b 4c 24 28 64 48 33 0c 25
> RSP: 002b:00007ffda4c16c20 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
> RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fe4d9e9312b
> RDX: 0000000000000941 RSI: 00007ffda4c17f33 RDI: 00000000ffffff9c
> RBP: 00007ffda4c17f33 R08: 0000000000000000 R09: 0000000000000000
> R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000941
> R13: 00007fe4d9f631a4 R14: 00007ffda4c17f33 R15: 0000000000000000
>  </TASK>
> 
> The buggy address belongs to the physical page:
> page:ffffea000405a2c0 refcount:0 mapcount:0 mapping:0000000000000000
> index:0x0 pfn:0x10168b
> flags: 0x2fffff80000000(node=0|zone=2|lastcpupid=0x1fffff)
> raw: 002fffff80000000 ffffea0004057788 ffffea000402dbc8 0000000000000000
> raw: 0000000000000000 0000000000170000 00000000ffffffff 0000000000000000
> page dumped because: kasan: bad access detected
> 
> Memory state around the buggy address:
>  ffff88810168af00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>  ffff88810168af80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >ffff88810168b000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
>                    ^
>  ffff88810168b080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
>  ffff88810168b100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
> ==================================================================
> Disabling lock debugging due to kernel taint
> 00000000: 58 44 44 33 5b 53 35 c2 00 00 00 00 00 00 00 78
> XDD3[S5........x
> XFS (sdb): Internal error xfs_dir2_data_use_free at line 1200 of file
> fs/xfs/libxfs/xfs_dir2_data.c.  Caller
> xfs_dir2_data_use_free+0x28a/0xeb0
> CPU: 5 PID: 1552 Comm: touch Tainted: G    B              6.0.0-rc3+
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
> 1.13.0-1ubuntu1.1 04/01/2014
> Call Trace:
>  <TASK>
>  dump_stack_lvl+0x4d/0x66
>  xfs_corruption_error+0x132/0x150
>  xfs_dir2_data_use_free+0x198/0xeb0
>  xfs_dir2_leaf_addname+0xa59/0x1ac0
>  xfs_dir_createname+0x58c/0x7f0
>  xfs_create+0x7af/0x1010
>  xfs_generic_create+0x270/0x5e0
>  path_openat+0x270b/0x3450
>  do_filp_open+0x1cf/0x2b0
>  do_sys_openat2+0x46b/0x7a0
>  do_sys_open+0xb7/0x130
>  do_syscall_64+0x35/0x80
>  entry_SYSCALL_64_after_hwframe+0x63/0xcd
> RIP: 0033:0x7fe4d9e9312b
> Code: 25 00 00 41 00 3d 00 00 41 00 74 4b 64 8b 04 25 18 00 00 00 85 c0
> 75 67 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00
> f0 ff ff 0f 87 91 00 00 00 48 8b 4c 24 28 64 48 33 0c 25
> RSP: 002b:00007ffda4c16c20 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
> RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fe4d9e9312b
> RDX: 0000000000000941 RSI: 00007ffda4c17f46 RDI: 00000000ffffff9c
> RBP: 00007ffda4c17f46 R08: 0000000000000000 R09: 0000000000000001
> R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000941
> R13: 00007fe4d9f631a4 R14: 00007ffda4c17f46 R15: 0000000000000000
>  </TASK>
> XFS (sdb): Corruption detected. Unmount and run xfs_repair
> 
> [1] https://lore.kernel.org/all/20220928095355.2074025-1-guoxuenan@huawei.com/
> Reviewed-by: Hou Tao <houtao1@huawei.com>
> Signed-off-by: Guo Xuenan <guoxuenan@huawei.com>
> ---
>  fs/xfs/libxfs/xfs_dir2_leaf.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> index d9b66306a9a7..bf4633b228cd 100644
> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> @@ -146,6 +146,7 @@ xfs_dir3_leaf_check_int(
>  	xfs_dir2_leaf_tail_t		*ltp;
>  	int				stale;
>  	int				i;
> +	xfs_dir2_db_t			db;
>  
>  	ltp = xfs_dir2_leaf_tail_p(geo, leaf);
>  
> @@ -175,6 +176,9 @@ xfs_dir3_leaf_check_int(
>  		}
>  		if (hdr->ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
>  			stale++;
> +		db = xfs_dir2_dataptr_to_db(geo, be32_to_cpu(hdr->ents[i].address));
> +		if (db >= be32_to_cpu(ltp->bestcount))
> +			return __this_address;

What about LEAFN blocks?  Those don't have a bests[] array or a
bestcount because the free space info is in the third directory
partition, so there's nothing to check here.  IIUC, only LEAF1 blocks
can compare bestcount to the entry addresses, right?

--D

>  	}
>  	if (hdr->stale != stale)
>  		return __this_address;
> -- 
> 2.25.1
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v4] xfs: fix exception caused by unexpected illegal bestcount in leaf dir
  2022-09-29 20:50     ` Darrick J. Wong
@ 2022-10-07 11:33       ` Guo Xuenan
  2022-10-07 16:30         ` Darrick J. Wong
  0 siblings, 1 reply; 9+ messages in thread
From: Guo Xuenan @ 2022-10-07 11:33 UTC (permalink / raw)
  To: Darrick J. Wong
  Cc: david, dchinner, chandan.babu, houtao1, jack.qiu, linux-xfs,
	yi.zhang, zhengbin13


On 2022/9/30 4:50, Darrick J. Wong wrote:
> On Thu, Sep 29, 2022 at 04:51:55PM +0800, Guo Xuenan wrote:
>> For leaf dir, In most cases, there should be as many bestfree slots
>> as the dir data blocks that can fit under i_size (except for [1]).
>>
>> Root cause is we don't examin the number bestfree slots, when the slots
>> number less than dir data blocks, if we need to allocate new dir data
>> block and update the bestfree array, we will use the dir block number as
>> index to assign bestfree array, while we did not check the leaf buf
>> boundary which may cause UAF or other memory access problem. This issue
>> can also triggered with test cases xfs/473 from fstests.
>>
>> According to Dave Chinner & Darrick's suggestion, adding buffer verifier
>> to detect this abnormal situation in time.
>> Simplify the testcase for fstest xfs/554 [1]
>>
>> The error log is shown as follows:
>> ==================================================================
>> BUG: KASAN: use-after-free in xfs_dir2_leaf_addname+0x1995/0x1ac0
>> Write of size 2 at addr ffff88810168b000 by task touch/1552
>> CPU: 5 PID: 1552 Comm: touch Not tainted 6.0.0-rc3+ #101
>> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
>> 1.13.0-1ubuntu1.1 04/01/2014
>> Call Trace:
>>   <TASK>
>>   dump_stack_lvl+0x4d/0x66
>>   print_report.cold+0xf6/0x691
>>   kasan_report+0xa8/0x120
>>   xfs_dir2_leaf_addname+0x1995/0x1ac0
>>   xfs_dir_createname+0x58c/0x7f0
>>   xfs_create+0x7af/0x1010
>>   xfs_generic_create+0x270/0x5e0
>>   path_openat+0x270b/0x3450
>>   do_filp_open+0x1cf/0x2b0
>>   do_sys_openat2+0x46b/0x7a0
>>   do_sys_open+0xb7/0x130
>>   do_syscall_64+0x35/0x80
>>   entry_SYSCALL_64_after_hwframe+0x63/0xcd
>> RIP: 0033:0x7fe4d9e9312b
>> Code: 25 00 00 41 00 3d 00 00 41 00 74 4b 64 8b 04 25 18 00 00 00 85 c0
>> 75 67 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00
>> f0 ff ff 0f 87 91 00 00 00 48 8b 4c 24 28 64 48 33 0c 25
>> RSP: 002b:00007ffda4c16c20 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
>> RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fe4d9e9312b
>> RDX: 0000000000000941 RSI: 00007ffda4c17f33 RDI: 00000000ffffff9c
>> RBP: 00007ffda4c17f33 R08: 0000000000000000 R09: 0000000000000000
>> R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000941
>> R13: 00007fe4d9f631a4 R14: 00007ffda4c17f33 R15: 0000000000000000
>>   </TASK>
>>
>> The buggy address belongs to the physical page:
>> page:ffffea000405a2c0 refcount:0 mapcount:0 mapping:0000000000000000
>> index:0x0 pfn:0x10168b
>> flags: 0x2fffff80000000(node=0|zone=2|lastcpupid=0x1fffff)
>> raw: 002fffff80000000 ffffea0004057788 ffffea000402dbc8 0000000000000000
>> raw: 0000000000000000 0000000000170000 00000000ffffffff 0000000000000000
>> page dumped because: kasan: bad access detected
>>
>> Memory state around the buggy address:
>>   ffff88810168af00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>   ffff88810168af80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>> ffff88810168b000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
>>                     ^
>>   ffff88810168b080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
>>   ffff88810168b100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
>> ==================================================================
>> Disabling lock debugging due to kernel taint
>> 00000000: 58 44 44 33 5b 53 35 c2 00 00 00 00 00 00 00 78
>> XDD3[S5........x
>> XFS (sdb): Internal error xfs_dir2_data_use_free at line 1200 of file
>> fs/xfs/libxfs/xfs_dir2_data.c.  Caller
>> xfs_dir2_data_use_free+0x28a/0xeb0
>> CPU: 5 PID: 1552 Comm: touch Tainted: G    B              6.0.0-rc3+
>> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
>> 1.13.0-1ubuntu1.1 04/01/2014
>> Call Trace:
>>   <TASK>
>>   dump_stack_lvl+0x4d/0x66
>>   xfs_corruption_error+0x132/0x150
>>   xfs_dir2_data_use_free+0x198/0xeb0
>>   xfs_dir2_leaf_addname+0xa59/0x1ac0
>>   xfs_dir_createname+0x58c/0x7f0
>>   xfs_create+0x7af/0x1010
>>   xfs_generic_create+0x270/0x5e0
>>   path_openat+0x270b/0x3450
>>   do_filp_open+0x1cf/0x2b0
>>   do_sys_openat2+0x46b/0x7a0
>>   do_sys_open+0xb7/0x130
>>   do_syscall_64+0x35/0x80
>>   entry_SYSCALL_64_after_hwframe+0x63/0xcd
>> RIP: 0033:0x7fe4d9e9312b
>> Code: 25 00 00 41 00 3d 00 00 41 00 74 4b 64 8b 04 25 18 00 00 00 85 c0
>> 75 67 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00
>> f0 ff ff 0f 87 91 00 00 00 48 8b 4c 24 28 64 48 33 0c 25
>> RSP: 002b:00007ffda4c16c20 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
>> RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fe4d9e9312b
>> RDX: 0000000000000941 RSI: 00007ffda4c17f46 RDI: 00000000ffffff9c
>> RBP: 00007ffda4c17f46 R08: 0000000000000000 R09: 0000000000000001
>> R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000941
>> R13: 00007fe4d9f631a4 R14: 00007ffda4c17f46 R15: 0000000000000000
>>   </TASK>
>> XFS (sdb): Corruption detected. Unmount and run xfs_repair
>>
>> [1] https://lore.kernel.org/all/20220928095355.2074025-1-guoxuenan@huawei.com/
>> Reviewed-by: Hou Tao <houtao1@huawei.com>
>> Signed-off-by: Guo Xuenan <guoxuenan@huawei.com>
>> ---
>>   fs/xfs/libxfs/xfs_dir2_leaf.c | 4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
>> index d9b66306a9a7..bf4633b228cd 100644
>> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
>> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
>> @@ -146,6 +146,7 @@ xfs_dir3_leaf_check_int(
>>   	xfs_dir2_leaf_tail_t		*ltp;
>>   	int				stale;
>>   	int				i;
>> +	xfs_dir2_db_t			db;
>>   
>>   	ltp = xfs_dir2_leaf_tail_p(geo, leaf);
>>   
>> @@ -175,6 +176,9 @@ xfs_dir3_leaf_check_int(
>>   		}
>>   		if (hdr->ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
>>   			stale++;
>> +		db = xfs_dir2_dataptr_to_db(geo, be32_to_cpu(hdr->ents[i].address));
>> +		if (db >= be32_to_cpu(ltp->bestcount))
>> +			return __this_address;
> What about LEAFN blocks?  Those don't have a bests[] array or a
> bestcount because the free space info is in the third directory
> partition, so there's nothing to check here.  IIUC, only LEAF1 blocks
> can compare bestcount to the entry addresses, right?
Hi, Darrick:

Sorry for the late reply, I was on vacation last week.I have confirmed 
it, you're right,may we
need add an additional restriction, compare only LEAF1 block.

According to the problem you pointed out, amend as below. Looking 
forward for your valuable suggestions :)

diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index d9b66306a9a7..cd9ff1322445 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -175,6 +175,12 @@ xfs_dir3_leaf_check_int(
                 }
                 if (hdr->ents[i].address == 
cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
                         stale++;
+               if ((hdr->magic == XFS_DIR2_LEAF1_MAGIC ||
+                       hdr->magic == XFS_DIR3_LEAF1_MAGIC) &&
+                       xfs_dir2_dataptr_to_db(geo,
+ be32_to_cpu(hdr->ents[i].address))
+                                       >= be32_to_cpu(ltp->bestcount))
+                       return __this_address;
         }
         if (hdr->stale != stale)
                 return __this_address;



Thanks
Xuenan
> --D
>
>>   	}
>>   	if (hdr->stale != stale)
>>   		return __this_address;
>> -- 
>> 2.25.1
>>
> .

-- 
Guo Xuenan
-----------------------------
Email: guoxuenan@huawei.com


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v4] xfs: fix exception caused by unexpected illegal bestcount in leaf dir
  2022-10-07 11:33       ` Guo Xuenan
@ 2022-10-07 16:30         ` Darrick J. Wong
  2022-10-08  3:36           ` [PATCH v5] " Guo Xuenan
  0 siblings, 1 reply; 9+ messages in thread
From: Darrick J. Wong @ 2022-10-07 16:30 UTC (permalink / raw)
  To: Guo Xuenan
  Cc: david, dchinner, chandan.babu, houtao1, jack.qiu, linux-xfs,
	yi.zhang, zhengbin13

On Fri, Oct 07, 2022 at 07:33:53PM +0800, Guo Xuenan wrote:
> 
> On 2022/9/30 4:50, Darrick J. Wong wrote:
> > On Thu, Sep 29, 2022 at 04:51:55PM +0800, Guo Xuenan wrote:
> > > For leaf dir, In most cases, there should be as many bestfree slots
> > > as the dir data blocks that can fit under i_size (except for [1]).
> > > 
> > > Root cause is we don't examin the number bestfree slots, when the slots
> > > number less than dir data blocks, if we need to allocate new dir data
> > > block and update the bestfree array, we will use the dir block number as
> > > index to assign bestfree array, while we did not check the leaf buf
> > > boundary which may cause UAF or other memory access problem. This issue
> > > can also triggered with test cases xfs/473 from fstests.
> > > 
> > > According to Dave Chinner & Darrick's suggestion, adding buffer verifier
> > > to detect this abnormal situation in time.
> > > Simplify the testcase for fstest xfs/554 [1]
> > > 
> > > The error log is shown as follows:
> > > ==================================================================
> > > BUG: KASAN: use-after-free in xfs_dir2_leaf_addname+0x1995/0x1ac0
> > > Write of size 2 at addr ffff88810168b000 by task touch/1552
> > > CPU: 5 PID: 1552 Comm: touch Not tainted 6.0.0-rc3+ #101
> > > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
> > > 1.13.0-1ubuntu1.1 04/01/2014
> > > Call Trace:
> > >   <TASK>
> > >   dump_stack_lvl+0x4d/0x66
> > >   print_report.cold+0xf6/0x691
> > >   kasan_report+0xa8/0x120
> > >   xfs_dir2_leaf_addname+0x1995/0x1ac0
> > >   xfs_dir_createname+0x58c/0x7f0
> > >   xfs_create+0x7af/0x1010
> > >   xfs_generic_create+0x270/0x5e0
> > >   path_openat+0x270b/0x3450
> > >   do_filp_open+0x1cf/0x2b0
> > >   do_sys_openat2+0x46b/0x7a0
> > >   do_sys_open+0xb7/0x130
> > >   do_syscall_64+0x35/0x80
> > >   entry_SYSCALL_64_after_hwframe+0x63/0xcd
> > > RIP: 0033:0x7fe4d9e9312b
> > > Code: 25 00 00 41 00 3d 00 00 41 00 74 4b 64 8b 04 25 18 00 00 00 85 c0
> > > 75 67 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00
> > > f0 ff ff 0f 87 91 00 00 00 48 8b 4c 24 28 64 48 33 0c 25
> > > RSP: 002b:00007ffda4c16c20 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
> > > RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fe4d9e9312b
> > > RDX: 0000000000000941 RSI: 00007ffda4c17f33 RDI: 00000000ffffff9c
> > > RBP: 00007ffda4c17f33 R08: 0000000000000000 R09: 0000000000000000
> > > R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000941
> > > R13: 00007fe4d9f631a4 R14: 00007ffda4c17f33 R15: 0000000000000000
> > >   </TASK>
> > > 
> > > The buggy address belongs to the physical page:
> > > page:ffffea000405a2c0 refcount:0 mapcount:0 mapping:0000000000000000
> > > index:0x0 pfn:0x10168b
> > > flags: 0x2fffff80000000(node=0|zone=2|lastcpupid=0x1fffff)
> > > raw: 002fffff80000000 ffffea0004057788 ffffea000402dbc8 0000000000000000
> > > raw: 0000000000000000 0000000000170000 00000000ffffffff 0000000000000000
> > > page dumped because: kasan: bad access detected
> > > 
> > > Memory state around the buggy address:
> > >   ffff88810168af00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > >   ffff88810168af80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > > > ffff88810168b000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
> > >                     ^
> > >   ffff88810168b080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
> > >   ffff88810168b100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
> > > ==================================================================
> > > Disabling lock debugging due to kernel taint
> > > 00000000: 58 44 44 33 5b 53 35 c2 00 00 00 00 00 00 00 78
> > > XDD3[S5........x
> > > XFS (sdb): Internal error xfs_dir2_data_use_free at line 1200 of file
> > > fs/xfs/libxfs/xfs_dir2_data.c.  Caller
> > > xfs_dir2_data_use_free+0x28a/0xeb0
> > > CPU: 5 PID: 1552 Comm: touch Tainted: G    B              6.0.0-rc3+
> > > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
> > > 1.13.0-1ubuntu1.1 04/01/2014
> > > Call Trace:
> > >   <TASK>
> > >   dump_stack_lvl+0x4d/0x66
> > >   xfs_corruption_error+0x132/0x150
> > >   xfs_dir2_data_use_free+0x198/0xeb0
> > >   xfs_dir2_leaf_addname+0xa59/0x1ac0
> > >   xfs_dir_createname+0x58c/0x7f0
> > >   xfs_create+0x7af/0x1010
> > >   xfs_generic_create+0x270/0x5e0
> > >   path_openat+0x270b/0x3450
> > >   do_filp_open+0x1cf/0x2b0
> > >   do_sys_openat2+0x46b/0x7a0
> > >   do_sys_open+0xb7/0x130
> > >   do_syscall_64+0x35/0x80
> > >   entry_SYSCALL_64_after_hwframe+0x63/0xcd
> > > RIP: 0033:0x7fe4d9e9312b
> > > Code: 25 00 00 41 00 3d 00 00 41 00 74 4b 64 8b 04 25 18 00 00 00 85 c0
> > > 75 67 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00
> > > f0 ff ff 0f 87 91 00 00 00 48 8b 4c 24 28 64 48 33 0c 25
> > > RSP: 002b:00007ffda4c16c20 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
> > > RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fe4d9e9312b
> > > RDX: 0000000000000941 RSI: 00007ffda4c17f46 RDI: 00000000ffffff9c
> > > RBP: 00007ffda4c17f46 R08: 0000000000000000 R09: 0000000000000001
> > > R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000941
> > > R13: 00007fe4d9f631a4 R14: 00007ffda4c17f46 R15: 0000000000000000
> > >   </TASK>
> > > XFS (sdb): Corruption detected. Unmount and run xfs_repair
> > > 
> > > [1] https://lore.kernel.org/all/20220928095355.2074025-1-guoxuenan@huawei.com/
> > > Reviewed-by: Hou Tao <houtao1@huawei.com>
> > > Signed-off-by: Guo Xuenan <guoxuenan@huawei.com>
> > > ---
> > >   fs/xfs/libxfs/xfs_dir2_leaf.c | 4 ++++
> > >   1 file changed, 4 insertions(+)
> > > 
> > > diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> > > index d9b66306a9a7..bf4633b228cd 100644
> > > --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> > > +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> > > @@ -146,6 +146,7 @@ xfs_dir3_leaf_check_int(
> > >   	xfs_dir2_leaf_tail_t		*ltp;
> > >   	int				stale;
> > >   	int				i;
> > > +	xfs_dir2_db_t			db;
> > >   	ltp = xfs_dir2_leaf_tail_p(geo, leaf);
> > > @@ -175,6 +176,9 @@ xfs_dir3_leaf_check_int(
> > >   		}
> > >   		if (hdr->ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
> > >   			stale++;
> > > +		db = xfs_dir2_dataptr_to_db(geo, be32_to_cpu(hdr->ents[i].address));
> > > +		if (db >= be32_to_cpu(ltp->bestcount))
> > > +			return __this_address;
> > What about LEAFN blocks?  Those don't have a bests[] array or a
> > bestcount because the free space info is in the third directory
> > partition, so there's nothing to check here.  IIUC, only LEAF1 blocks
> > can compare bestcount to the entry addresses, right?
> Hi, Darrick:
> 
> Sorry for the late reply, I was on vacation last week.I have confirmed it,
> you're right,may we
> need add an additional restriction, compare only LEAF1 block.
> 
> According to the problem you pointed out, amend as below. Looking forward
> for your valuable suggestions :)
> 
> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
> index d9b66306a9a7..cd9ff1322445 100644
> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c
> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
> @@ -175,6 +175,12 @@ xfs_dir3_leaf_check_int(
>                 }
>                 if (hdr->ents[i].address ==
> cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
>                         stale++;
> +               if ((hdr->magic == XFS_DIR2_LEAF1_MAGIC ||
> +                       hdr->magic == XFS_DIR3_LEAF1_MAGIC) &&
> +                       xfs_dir2_dataptr_to_db(geo,
> + be32_to_cpu(hdr->ents[i].address))
> +                                       >= be32_to_cpu(ltp->bestcount))
> +                       return __this_address;

That looks like a reasonable amendment to the code, though you might
hoist the leaf1 detection to a local variable so that we don't have to
do the same comparison multiple times in the same function.

	bool isleaf1 = (hdr->magic == XFS_DIR2_LEAF1_MAGIC ||
			hdr->magic == XFS_DIR3_LEAF1_MAGIC);

	/* Leaves and bests don't overlap in leaf format. */
	if (isleaf1 &&
	    (char *)&hdr->ents[hdr->count] > (char *)xfs_dir2_leaf_bests_p(ltp))
		return __this_address;

	...

		if (isleaf1 &&
		    xfs_dir2_dataptr_to_db(geo,
					be32_to_cpu(hdr->ents[i].address)) >=
					be32_to_cpu(ltp->bestcount))
				return __this_address;

Or something like that.

--D

>         }
>         if (hdr->stale != stale)
>                 return __this_address;
> 
> 
> 
> Thanks
> Xuenan
> > --D
> > 
> > >   	}
> > >   	if (hdr->stale != stale)
> > >   		return __this_address;
> > > -- 
> > > 2.25.1
> > > 
> > .
> 
> -- 
> Guo Xuenan
> -----------------------------
> Email: guoxuenan@huawei.com
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v5] xfs: fix exception caused by unexpected illegal bestcount in leaf dir
  2022-10-07 16:30         ` Darrick J. Wong
@ 2022-10-08  3:36           ` Guo Xuenan
  0 siblings, 0 replies; 9+ messages in thread
From: Guo Xuenan @ 2022-10-08  3:36 UTC (permalink / raw)
  To: djwong
  Cc: chandan.babu, david, dchinner, guoxuenan, houtao1, jack.qiu,
	linux-xfs, yi.zhang, zhengbin13

For leaf dir, In most cases, there should be as many bestfree slots
as the dir data blocks that can fit under i_size (except for [1]).

Root cause is we don't examin the number bestfree slots, when the slots
number less than dir data blocks, if we need to allocate new dir data
block and update the bestfree array, we will use the dir block number as
index to assign bestfree array, while we did not check the leaf buf
boundary which may cause UAF or other memory access problem. This issue
can also triggered with test cases xfs/473 from fstests.

According to Dave Chinner & Darrick's suggestion, adding buffer verifier
to detect this abnormal situation in time.
Simplify the testcase for fstest xfs/554 [1]

The error log is shown as follows:
==================================================================
BUG: KASAN: use-after-free in xfs_dir2_leaf_addname+0x1995/0x1ac0
Write of size 2 at addr ffff88810168b000 by task touch/1552
CPU: 5 PID: 1552 Comm: touch Not tainted 6.0.0-rc3+ #101
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.13.0-1ubuntu1.1 04/01/2014
Call Trace:
 <TASK>
 dump_stack_lvl+0x4d/0x66
 print_report.cold+0xf6/0x691
 kasan_report+0xa8/0x120
 xfs_dir2_leaf_addname+0x1995/0x1ac0
 xfs_dir_createname+0x58c/0x7f0
 xfs_create+0x7af/0x1010
 xfs_generic_create+0x270/0x5e0
 path_openat+0x270b/0x3450
 do_filp_open+0x1cf/0x2b0
 do_sys_openat2+0x46b/0x7a0
 do_sys_open+0xb7/0x130
 do_syscall_64+0x35/0x80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x7fe4d9e9312b
Code: 25 00 00 41 00 3d 00 00 41 00 74 4b 64 8b 04 25 18 00 00 00 85 c0
75 67 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00
f0 ff ff 0f 87 91 00 00 00 48 8b 4c 24 28 64 48 33 0c 25
RSP: 002b:00007ffda4c16c20 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fe4d9e9312b
RDX: 0000000000000941 RSI: 00007ffda4c17f33 RDI: 00000000ffffff9c
RBP: 00007ffda4c17f33 R08: 0000000000000000 R09: 0000000000000000
R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000941
R13: 00007fe4d9f631a4 R14: 00007ffda4c17f33 R15: 0000000000000000
 </TASK>

The buggy address belongs to the physical page:
page:ffffea000405a2c0 refcount:0 mapcount:0 mapping:0000000000000000
index:0x0 pfn:0x10168b
flags: 0x2fffff80000000(node=0|zone=2|lastcpupid=0x1fffff)
raw: 002fffff80000000 ffffea0004057788 ffffea000402dbc8 0000000000000000
raw: 0000000000000000 0000000000170000 00000000ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff88810168af00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ffff88810168af80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffff88810168b000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
                   ^
 ffff88810168b080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 ffff88810168b100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
==================================================================
Disabling lock debugging due to kernel taint
00000000: 58 44 44 33 5b 53 35 c2 00 00 00 00 00 00 00 78
XDD3[S5........x
XFS (sdb): Internal error xfs_dir2_data_use_free at line 1200 of file
fs/xfs/libxfs/xfs_dir2_data.c.  Caller
xfs_dir2_data_use_free+0x28a/0xeb0
CPU: 5 PID: 1552 Comm: touch Tainted: G    B              6.0.0-rc3+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.13.0-1ubuntu1.1 04/01/2014
Call Trace:
 <TASK>
 dump_stack_lvl+0x4d/0x66
 xfs_corruption_error+0x132/0x150
 xfs_dir2_data_use_free+0x198/0xeb0
 xfs_dir2_leaf_addname+0xa59/0x1ac0
 xfs_dir_createname+0x58c/0x7f0
 xfs_create+0x7af/0x1010
 xfs_generic_create+0x270/0x5e0
 path_openat+0x270b/0x3450
 do_filp_open+0x1cf/0x2b0
 do_sys_openat2+0x46b/0x7a0
 do_sys_open+0xb7/0x130
 do_syscall_64+0x35/0x80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x7fe4d9e9312b
Code: 25 00 00 41 00 3d 00 00 41 00 74 4b 64 8b 04 25 18 00 00 00 85 c0
75 67 44 89 e2 48 89 ee bf 9c ff ff ff b8 01 01 00 00 0f 05 <48> 3d 00
f0 ff ff 0f 87 91 00 00 00 48 8b 4c 24 28 64 48 33 0c 25
RSP: 002b:00007ffda4c16c20 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007fe4d9e9312b
RDX: 0000000000000941 RSI: 00007ffda4c17f46 RDI: 00000000ffffff9c
RBP: 00007ffda4c17f46 R08: 0000000000000000 R09: 0000000000000001
R10: 00000000000001b6 R11: 0000000000000246 R12: 0000000000000941
R13: 00007fe4d9f631a4 R14: 00007ffda4c17f46 R15: 0000000000000000
 </TASK>
XFS (sdb): Corruption detected. Unmount and run xfs_repair

[1] https://lore.kernel.org/all/20220928095355.2074025-1-guoxuenan@huawei.com/
Reviewed-by: Hou Tao <houtao1@huawei.com>
Signed-off-by: Guo Xuenan <guoxuenan@huawei.com>
---
 fs/xfs/libxfs/xfs_dir2_leaf.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c
index d9b66306a9a7..cb9e950a911d 100644
--- a/fs/xfs/libxfs/xfs_dir2_leaf.c
+++ b/fs/xfs/libxfs/xfs_dir2_leaf.c
@@ -146,6 +146,8 @@ xfs_dir3_leaf_check_int(
 	xfs_dir2_leaf_tail_t		*ltp;
 	int				stale;
 	int				i;
+	bool				isleaf1 = (hdr->magic == XFS_DIR2_LEAF1_MAGIC ||
+						   hdr->magic == XFS_DIR3_LEAF1_MAGIC);
 
 	ltp = xfs_dir2_leaf_tail_p(geo, leaf);
 
@@ -158,8 +160,7 @@ xfs_dir3_leaf_check_int(
 		return __this_address;
 
 	/* Leaves and bests don't overlap in leaf format. */
-	if ((hdr->magic == XFS_DIR2_LEAF1_MAGIC ||
-	     hdr->magic == XFS_DIR3_LEAF1_MAGIC) &&
+	if (isleaf1 &&
 	    (char *)&hdr->ents[hdr->count] > (char *)xfs_dir2_leaf_bests_p(ltp))
 		return __this_address;
 
@@ -175,6 +176,10 @@ xfs_dir3_leaf_check_int(
 		}
 		if (hdr->ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
 			stale++;
+		if (isleaf1 && xfs_dir2_dataptr_to_db(geo,
+				be32_to_cpu(hdr->ents[i].address)) >=
+				be32_to_cpu(ltp->bestcount))
+			return __this_address;
 	}
 	if (hdr->stale != stale)
 		return __this_address;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-10-08  3:10 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-31 12:16 [PATCH v2] xfs: fix uaf when leaf dir bestcount not match with dir data blocks Guo Xuenan
2022-09-12  1:31 ` Dave Chinner
2022-09-14 16:30   ` Darrick J. Wong
2022-09-28 10:06   ` [PATCH v3] xfs: fix expection caused by unexpected illegal bestcount in leaf dir Guo Xuenan
2022-09-29  8:51   ` [PATCH v4] xfs: fix exception " Guo Xuenan
2022-09-29 20:50     ` Darrick J. Wong
2022-10-07 11:33       ` Guo Xuenan
2022-10-07 16:30         ` Darrick J. Wong
2022-10-08  3:36           ` [PATCH v5] " Guo Xuenan

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.