From nobody Mon Feb 9 08:56:35 2026 Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6C81415381C; Wed, 21 Aug 2024 15:23:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.60.130.6 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724253838; cv=none; b=gIRnjs6e3OOFyuNHnUl7OmQN+ic8O1Z/Y7Nj0huNW0E3Ucj/smrgB7ElyxViUGp/4DwnPsUQys8q+21zmX6mNgFmwqpvelbOETREc262Ta4lXXk+PNmZKaEqKhB16PN7AsHYJOXd1DwfYjx2tAc8EJD1TfbbePb4vnoyez8i/Dc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724253838; c=relaxed/simple; bh=5BsHw2kYHnsz/r6of4wdwt+9bFTxxskxWt0Tv6wYjbA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ecghUvoqp/lPoac6zW6x2DsBleh6H0hUqtxq+7T94OwRWoUnCB+Vld7NhfyRDYODmyZirhBGJ9/wBVhnlixyotQGos5/tCaxoC7eoAmiffP3KyEQkL/VhtxX+xad37bcXeF79MLfEFXFaZMW9iZ2n+NqkMuPbjpS7cMke5nul+Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com; spf=pass smtp.mailfrom=igalia.com; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b=gN/+mpPD; arc=none smtp.client-ip=178.60.130.6 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=igalia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="gN/+mpPD" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=tnW4fUEYIqoKL4+ireuq+NgRn+HNA1V4t/qdy5l68Ns=; b=gN/+mpPD1uP3NN4dlsZMgU62/q XeFzP80BStqiAXSz548tZTrdD8O76cNDGN8b7NtE20/RortV6pLDJmAN0bvqW9xjaiDoHBGlfzxGX 1XPmfiW4GSxCheZ/1qEGuK+90Ebcmfbcbt6dHv5s47r66jGYs2xx0+Zx5fffuo/Mbcomjh/0Ic5Yu xPU1HVQ9sSvr8noC427hDwfBSlG+ytxifxekXRcHbtIYYF+MiZaxZ+o1nhS53KLm9daBCH9Do9ota dk682/TyJLit3H1f1nDaA6MNOPTjw/LHtBmGHJkyPKHdx7lzo6nxqehglqmYUNWrjjCnwWETCJFRm PKM8O10A==; Received: from 179-125-75-209-dinamico.pombonet.net.br ([179.125.75.209] helo=quatroqueijos.lan) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1sgnBi-0034iV-DH; Wed, 21 Aug 2024 17:23:54 +0200 From: Thadeu Lima de Souza Cascardo To: linux-ext4@vger.kernel.org Cc: Theodore Ts'o , linux-kernel@vger.kernel.org, Tao Ma , Andreas Dilger , kernel-dev@igalia.com, Thadeu Lima de Souza Cascardo , syzbot+0c2508114d912a54ee79@syzkaller.appspotmail.com Subject: [PATCH 4/4] ext4: avoid OOB when system.data xattr changes underneath the filesystem Date: Wed, 21 Aug 2024 12:23:24 -0300 Message-Id: <20240821152324.3621860-5-cascardo@igalia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240821152324.3621860-1-cascardo@igalia.com> References: <20240821152324.3621860-1-cascardo@igalia.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When looking up for an entry in an inlined directory, if e_value_offs is changed underneath the filesystem by some change in the block device, it will lead to an out-of-bounds access that KASAN detects as an UAF. EXT4-fs (loop0): mounted filesystem 00000000-0000-0000-0000-000000000000 r/= w without journal. Quota mode: none. loop0: detected capacity change from 2048 to 2047 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D BUG: KASAN: use-after-free in ext4_search_dir+0xf2/0x1c0 fs/ext4/namei.c:15= 00 Read of size 1 at addr ffff88803e91130f by task syz-executor269/5103 CPU: 0 UID: 0 PID: 5103 Comm: syz-executor269 Not tainted 6.11.0-rc4-syzkal= ler #0 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16= .3-2~bpo12+1 04/01/2014 Call Trace: __dump_stack lib/dump_stack.c:93 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:119 print_address_description mm/kasan/report.c:377 [inline] print_report+0x169/0x550 mm/kasan/report.c:488 kasan_report+0x143/0x180 mm/kasan/report.c:601 ext4_search_dir+0xf2/0x1c0 fs/ext4/namei.c:1500 ext4_find_inline_entry+0x4be/0x5e0 fs/ext4/inline.c:1697 __ext4_find_entry+0x2b4/0x1b30 fs/ext4/namei.c:1573 ext4_lookup_entry fs/ext4/namei.c:1727 [inline] ext4_lookup+0x15f/0x750 fs/ext4/namei.c:1795 lookup_one_qstr_excl+0x11f/0x260 fs/namei.c:1633 filename_create+0x297/0x540 fs/namei.c:3980 do_symlinkat+0xf9/0x3a0 fs/namei.c:4587 __do_sys_symlinkat fs/namei.c:4610 [inline] __se_sys_symlinkat fs/namei.c:4607 [inline] __x64_sys_symlinkat+0x95/0xb0 fs/namei.c:4607 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f3e73ced469 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 21 18 00 00 90 48 89 f8 48 89 f7 = 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff f= f 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fff4d40c258 EFLAGS: 00000246 ORIG_RAX: 000000000000010a RAX: ffffffffffffffda RBX: 0032656c69662f2e RCX: 00007f3e73ced469 RDX: 0000000020000200 RSI: 00000000ffffff9c RDI: 00000000200001c0 RBP: 0000000000000000 R08: 00007fff4d40c290 R09: 00007fff4d40c290 R10: 0023706f6f6c2f76 R11: 0000000000000246 R12: 00007fff4d40c27c R13: 0000000000000003 R14: 431bde82d7b634db R15: 00007fff4d40c2b0 Calling ext4_xattr_ibody_find right after reading the inode with ext4_get_inode_loc will lead to a check of the validity of the xattrs, avoiding this problem. Reported-by: syzbot+0c2508114d912a54ee79@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=3D0c2508114d912a54ee79 Fixes: e8e948e7802a ("ext4: let ext4_find_entry handle inline data") Signed-off-by: Thadeu Lima de Souza Cascardo --- fs/ext4/inline.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 7b98b1bf1dc9..44a5f6df59ec 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -1664,25 +1664,36 @@ struct buffer_head *ext4_find_inline_entry(struct i= node *dir, struct ext4_dir_entry_2 **res_dir, int *has_inline_data) { + struct ext4_xattr_ibody_find is =3D { + .s =3D { .not_found =3D -ENODATA, }, + }; + struct ext4_xattr_info i =3D { + .name_index =3D EXT4_XATTR_INDEX_SYSTEM, + .name =3D EXT4_XATTR_SYSTEM_DATA, + }; int ret; - struct ext4_iloc iloc; void *inline_start; int inline_size; =20 - ret =3D ext4_get_inode_loc(dir, &iloc); + ret =3D ext4_get_inode_loc(dir, &is.iloc); if (ret) return ERR_PTR(ret); =20 down_read(&EXT4_I(dir)->xattr_sem); + + ret =3D ext4_xattr_ibody_find(dir, &i, &is); + if (ret) + goto out; + if (!ext4_has_inline_data(dir)) { *has_inline_data =3D 0; goto out; } =20 - inline_start =3D (void *)ext4_raw_inode(&iloc)->i_block + + inline_start =3D (void *)ext4_raw_inode(&is.iloc)->i_block + EXT4_INLINE_DOTDOT_SIZE; inline_size =3D EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DOTDOT_SIZE; - ret =3D ext4_search_dir(iloc.bh, inline_start, inline_size, + ret =3D ext4_search_dir(is.iloc.bh, inline_start, inline_size, dir, fname, 0, res_dir); if (ret =3D=3D 1) goto out_find; @@ -1692,23 +1703,23 @@ struct buffer_head *ext4_find_inline_entry(struct i= node *dir, if (ext4_get_inline_size(dir) =3D=3D EXT4_MIN_INLINE_DATA_SIZE) goto out; =20 - inline_start =3D ext4_get_inline_xattr_pos(dir, &iloc); + inline_start =3D ext4_get_inline_xattr_pos(dir, &is.iloc); inline_size =3D ext4_get_inline_size(dir) - EXT4_MIN_INLINE_DATA_SIZE; =20 - ret =3D ext4_search_dir(iloc.bh, inline_start, inline_size, + ret =3D ext4_search_dir(is.iloc.bh, inline_start, inline_size, dir, fname, 0, res_dir); if (ret =3D=3D 1) goto out_find; =20 out: - brelse(iloc.bh); + brelse(is.iloc.bh); if (ret < 0) - iloc.bh =3D ERR_PTR(ret); + is.iloc.bh =3D ERR_PTR(ret); else - iloc.bh =3D NULL; + is.iloc.bh =3D NULL; out_find: up_read(&EXT4_I(dir)->xattr_sem); - return iloc.bh; + return is.iloc.bh; } =20 int ext4_delete_inline_entry(handle_t *handle, --=20 2.34.1