All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ritesh Harjani <ritesh.list@gmail.com>
To: Baokun Li <libaokun1@huawei.com>
Cc: linux-ext4@vger.kernel.org, tytso@mit.edu,
	adilger.kernel@dilger.ca, jack@suse.cz, lczerner@redhat.com,
	enwlinux@gmail.com, linux-kernel@vger.kernel.org,
	yi.zhang@huawei.com, yebin10@huawei.com, yukuai3@huawei.com,
	Hulk Robot <hulkci@huawei.com>
Subject: Re: [PATCH v3 2/4] ext4: fix use-after-free in ext4_xattr_set_entry
Date: Thu, 16 Jun 2022 09:32:40 +0530	[thread overview]
Message-ID: <20220616040240.wxftnctzfaboxziw@riteshh-domain> (raw)
In-Reply-To: <20220616021358.2504451-3-libaokun1@huawei.com>

On 22/06/16 10:13AM, Baokun Li wrote:
> Hulk Robot reported a issue:
> ==================================================================
> BUG: KASAN: use-after-free in ext4_xattr_set_entry+0x18ab/0x3500
> Write of size 4105 at addr ffff8881675ef5f4 by task syz-executor.0/7092
>
> CPU: 1 PID: 7092 Comm: syz-executor.0 Not tainted 4.19.90-dirty #17
> Call Trace:
> [...]
>  memcpy+0x34/0x50 mm/kasan/kasan.c:303
>  ext4_xattr_set_entry+0x18ab/0x3500 fs/ext4/xattr.c:1747
>  ext4_xattr_ibody_inline_set+0x86/0x2a0 fs/ext4/xattr.c:2205
>  ext4_xattr_set_handle+0x940/0x1300 fs/ext4/xattr.c:2386
>  ext4_xattr_set+0x1da/0x300 fs/ext4/xattr.c:2498
>  __vfs_setxattr+0x112/0x170 fs/xattr.c:149
>  __vfs_setxattr_noperm+0x11b/0x2a0 fs/xattr.c:180
>  __vfs_setxattr_locked+0x17b/0x250 fs/xattr.c:238
>  vfs_setxattr+0xed/0x270 fs/xattr.c:255
>  setxattr+0x235/0x330 fs/xattr.c:520
>  path_setxattr+0x176/0x190 fs/xattr.c:539
>  __do_sys_lsetxattr fs/xattr.c:561 [inline]
>  __se_sys_lsetxattr fs/xattr.c:557 [inline]
>  __x64_sys_lsetxattr+0xc2/0x160 fs/xattr.c:557
>  do_syscall_64+0xdf/0x530 arch/x86/entry/common.c:298
>  entry_SYSCALL_64_after_hwframe+0x44/0xa9
> RIP: 0033:0x459fe9
> RSP: 002b:00007fa5e54b4c08 EFLAGS: 00000246 ORIG_RAX: 00000000000000bd
> RAX: ffffffffffffffda RBX: 000000000051bf60 RCX: 0000000000459fe9
> RDX: 00000000200003c0 RSI: 0000000020000180 RDI: 0000000020000140
> RBP: 000000000051bf60 R08: 0000000000000001 R09: 0000000000000000
> R10: 0000000000001009 R11: 0000000000000246 R12: 0000000000000000
> R13: 00007ffc73c93fc0 R14: 000000000051bf60 R15: 00007fa5e54b4d80
> [...]
> ==================================================================
>
> Above issue may happen as follows:
> -------------------------------------
> ext4_xattr_set
>   ext4_xattr_set_handle
>     ext4_xattr_ibody_find
>       >> s->end < s->base
>       >> no EXT4_STATE_XATTR
>       >> xattr_check_inode is not executed
>     ext4_xattr_ibody_set
>       ext4_xattr_set_entry
>        >> size_t min_offs = s->end - s->base
>        >> UAF in memcpy
>
> we can easily reproduce this problem with the following commands:
>     mkfs.ext4 -F /dev/sda
>     mount -o debug_want_extra_isize=128 /dev/sda /mnt
>     touch /mnt/file
>     setfattr -n user.cat -v `seq -s z 4096|tr -d '[:digit:]'` /mnt/file

Thanks for sharing the test case. Indeed this results into UAF.

>
> In ext4_xattr_ibody_find, we have the following assignment logic:
>   header = IHDR(inode, raw_inode)
>          = raw_inode + EXT4_GOOD_OLD_INODE_SIZE + i_extra_isize
>   is->s.base = IFIRST(header)
>              = header + sizeof(struct ext4_xattr_ibody_header)
>   is->s.end = raw_inode + s_inode_size
>
> In ext4_xattr_set_entry
>   min_offs = s->end - s->base
>            = s_inode_size - EXT4_GOOD_OLD_INODE_SIZE - i_extra_isize -
> 	     sizeof(struct ext4_xattr_ibody_header)
>   last = s->first
>   free = min_offs - ((void *)last - s->base) - sizeof(__u32)
>        = s_inode_size - EXT4_GOOD_OLD_INODE_SIZE - i_extra_isize -
>          sizeof(struct ext4_xattr_ibody_header) - sizeof(__u32)
>
> In the calculation formula, all values except s_inode_size and
> i_extra_size are fixed values. When i_extra_size is the maximum value
> s_inode_size - EXT4_GOOD_OLD_INODE_SIZE, min_offs is -4 and free is -8.
> The value overflows. As a result, the preceding issue is triggered when
> memcpy is executed.
>
> Therefore, when finding xattr or setting xattr, check whether
> there is space for storing xattr in the inode to resolve this issue.

Sounds right. Thanks for fixing it and providing detailed analysis.

Feel free to add -

Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>


>
> Reported-by: Hulk Robot <hulkci@huawei.com>
> Signed-off-by: Baokun Li <libaokun1@huawei.com>
> ---
>  fs/ext4/xattr.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
> index 042325349098..c3c3194f3ee1 100644
> --- a/fs/ext4/xattr.c
> +++ b/fs/ext4/xattr.c
> @@ -2176,8 +2176,9 @@ int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
>  	struct ext4_inode *raw_inode;
>  	int error;
>
> -	if (EXT4_I(inode)->i_extra_isize == 0)
> +	if (!EXT4_INODE_HAS_XATTR_SPACE(inode))
>  		return 0;
> +
>  	raw_inode = ext4_raw_inode(&is->iloc);
>  	header = IHDR(inode, raw_inode);
>  	is->s.base = is->s.first = IFIRST(header);
> @@ -2205,8 +2206,9 @@ int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
>  	struct ext4_xattr_search *s = &is->s;
>  	int error;
>
> -	if (EXT4_I(inode)->i_extra_isize == 0)
> +	if (!EXT4_INODE_HAS_XATTR_SPACE(inode))
>  		return -ENOSPC;
> +
>  	error = ext4_xattr_set_entry(i, s, handle, inode, false /* is_block */);
>  	if (error)
>  		return error;
> --
> 2.31.1
>

  reply	other threads:[~2022-06-16  4:02 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-16  2:13 [PATCH v3 0/4] ext4: fix use-after-free in ext4_xattr_set_entry Baokun Li
2022-06-16  2:13 ` [PATCH v3 1/4] ext4: add EXT4_INODE_HAS_XATTR_SPACE macro in xattr.h Baokun Li
2022-06-16  4:00   ` Ritesh Harjani
2022-06-16 10:06   ` Jan Kara
2022-06-16  2:13 ` [PATCH v3 2/4] ext4: fix use-after-free in ext4_xattr_set_entry Baokun Li
2022-06-16  4:02   ` Ritesh Harjani [this message]
2022-06-16 10:07   ` Jan Kara
2022-06-16  2:13 ` [PATCH v3 3/4] ext4: correct max_inline_xattr_value_size computing Baokun Li
2022-06-16  4:04   ` Ritesh Harjani
2022-06-16 10:08   ` Jan Kara
2022-06-16  2:13 ` [PATCH v3 4/4] ext4: correct the misjudgment in ext4_iget_extra_inode Baokun Li
2022-06-16  4:08   ` Ritesh Harjani
2022-06-16 10:09   ` Jan Kara
2022-07-14 15:00 ` [PATCH v3 0/4] ext4: fix use-after-free in ext4_xattr_set_entry Theodore Ts'o
2022-07-22 13:58 ` Theodore Ts'o

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220616040240.wxftnctzfaboxziw@riteshh-domain \
    --to=ritesh.list@gmail.com \
    --cc=adilger.kernel@dilger.ca \
    --cc=enwlinux@gmail.com \
    --cc=hulkci@huawei.com \
    --cc=jack@suse.cz \
    --cc=lczerner@redhat.com \
    --cc=libaokun1@huawei.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tytso@mit.edu \
    --cc=yebin10@huawei.com \
    --cc=yi.zhang@huawei.com \
    --cc=yukuai3@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.