From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f172.google.com (mail-pf1-f172.google.com [209.85.210.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1E77819CD03 for ; Wed, 29 Apr 2026 02:20:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.172 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777429231; cv=none; b=iLkSHI3MsbnhVUsbzmq8DS2jTlz5KC70H3f//yBENs0T/oI+TeVoQE2YcRgRwqaQyBxel91PUmWbxbYg4poHmL55/LKpdf4yIFsi1utUJjq35/lshE5LptydMQgt5AxZ7ppZnS6+CiD36I+5ODzzcsX4QmCEMwP3K14Ihsi7Kkc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777429231; c=relaxed/simple; bh=Ke+9etmWZ1LmFVG84IReoMfK/YbTraDSF4t7TVPYwTg=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=kV1CzLUwsr8b4pQjE/LEb+eQ2DqQ/rM23mGNaJ5UVt/jxwuSH0YjJetDqbezCq/R5p+He6u4b9utQXaUxWXhgfAWCt3jKblqOOvm5wlrrfM0wER92CAW61dxxDqwURmuToK4FscIOVVnnEHwHZlnz2x3NBNOGFzboCJshsADSTU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lOkhaLzd; arc=none smtp.client-ip=209.85.210.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lOkhaLzd" Received: by mail-pf1-f172.google.com with SMTP id d2e1a72fcca58-82cebbdbdccso261456b3a.1 for ; Tue, 28 Apr 2026 19:20:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777429229; x=1778034029; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=ktD18KzMTUnc+4rPgU+clRQSsyYJUGFtwg9MNxlkxys=; b=lOkhaLzdnqWwIP/aeh5VeUxFombq7XXlJtGt6YFuZKAw09byT5FaHLSr7cvem/cnpJ q4+divApe/aW/oWHKD5bBcqKwtHXMLir87Mow6UKC9+2L2/p8PxAbqpcvJtRCux+hJ8g GKA8ZtybiPXU1lGujpr5hsejTiQSxyQ4Mcmoi0T8Oly1cNoCf+DaQkKTG4QnasZjEQMe AxizwsSO3m13Fh53EHAs6CmjSLFiKpAoeUhYd0CSL9n4YVI2NaUiCvAYEaq0pk4DNPe/ uHxmVqdq2orl83zXfY3KQfp5IyaAkfAmnRlnlAs9K+G2t0Av3XQ2v89XzlcTEosLG2CS L9DQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777429229; x=1778034029; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=ktD18KzMTUnc+4rPgU+clRQSsyYJUGFtwg9MNxlkxys=; b=LEwt+7mp33DBDuCaw532WWjrtjfI2zqOwVHDpcNsgmYa9NJdpQbKZJ6hxNsz/jsu/D A2f6gpTopi5gad4DGIfWt7ZzLG+2A7HERI5sH5OqFxrh6RcPhkacQ2hCrS9ViV6okk0n R/l9+yADZx7/fHUHP1GFZXdhXydGte4WqPu/f3a4FJuiPQWRUlhdkz3XsIfjwuoOm3R7 zbvUnSPjBWFfx/YTy3dAv8CQkoFufYS41rBywWads2zzgmTL6c09FaAxTqMsZJ+LtNLN R5uWUdk9/mh2rlp1OO2ERSrjptfI1TnvQBLojAADp+BAASQnngT+rJSgWV+BqJJWzPLu ALew== X-Forwarded-Encrypted: i=1; AFNElJ9hxI2n4Zipy5Zgs/f/o8YRvv9qrirf0O06qjoJ+GoM5mulkqW8Y/pOnPWsqAME+RgPROxx1ZTLE8lWcMM=@vger.kernel.org X-Gm-Message-State: AOJu0YwF6s6ZiK7n73XhE69BemBoCmv9Q+qvDYkFI+2pbWwipz2f/Co2 3Axcr05bljQb4rcTul3vbnk7BOjK77D4wsCRwNUmSS704Gwhox/0cowW X-Gm-Gg: AeBDiev0eOvJ7yBNwmVd5eidwOWMt5bNZLiL5TVyWWZy678ZikKRfz+HmwkiqN7R756 TI3Ij5CPeVk+9/WSpQU09wlV6ONjS4qJrS18eAFK/G/GnFnUZpqx6yAbsCtRs4+jP08RwtMpR9N Ruph69NHpksgzR/ZMY2N5xULanxIktqoT3WFeZcgvuB/RtFV7LfYfFBrHVlhkQMyBjMsmt9r81X jSHeXZs02HiPHtmSqziQH1X1u8R67eM2yLjdFXxriGKSP9XHCliFVN5lkaYKNx+GhK2frmB70Wd if1Mg9gdWl95jJH6NcSPVxelYE50BNnDOP4wQ4+xHIYY1We0x2k08FaNOLiF4hTWYubmI6uiNP5 aDjwAj4fADguBU+4DUpTKEzX2Wy2QAHvOOJOivM4MIEGhnatsoUlR/Nf5XdgiaJI8YdwKqSTCAX zET4G2+gTTyxoy7A5vZnGmlwyTYR75Ej9AtePjEy0fNRkQXZZ4smau0t+haGk50fF2wPMuCgvsK P17T5/n+Q== X-Received: by 2002:a05:6a00:2e93:b0:82f:2d48:f8fc with SMTP id d2e1a72fcca58-834eb3e4d01mr1175514b3a.6.1777429229252; Tue, 28 Apr 2026 19:20:29 -0700 (PDT) Received: from kernel-fuzz.. ([103.172.182.26]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-834ed5a1026sm425937b3a.4.2026.04.28.19.20.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Apr 2026 19:20:28 -0700 (PDT) From: ZhengYuan Huang To: mark@fasheh.com, jlbec@evilplan.org, joseph.qi@linux.alibaba.com Cc: ocfs2-devel@lists.linux.dev, linux-kernel@vger.kernel.org, baijiaju1990@gmail.com, r33s3n6@gmail.com, zzzccc427@gmail.com, ZhengYuan Huang Subject: [PATCH] ocfs2: validate local xattr value bounds on lookup Date: Wed, 29 Apr 2026 10:20:05 +0800 Message-ID: <20260429022005.1461600-1-gality369@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit [BUG] A corrupted local xattr entry can crash ACL lookup during open. BUG: KASAN: use-after-free in ocfs2_xattr_block_get fs/ocfs2/xattr.c:1261 [inline] BUG: KASAN: use-after-free in ocfs2_xattr_get_nolock+0x8cb/0x1110 fs/ocfs2/xattr.c:1312 Read of size 252 at addr ffff88801e7dbfb8 by task syz.0.1/347 Call Trace: ... ocfs2_xattr_block_get fs/ocfs2/xattr.c:1261 [inline] ocfs2_xattr_get_nolock+0x8cb/0x1110 fs/ocfs2/xattr.c:1312 ocfs2_get_acl_nolock+0xb1/0x3d0 fs/ocfs2/acl.c:137 ocfs2_iop_get_acl+0x197/0x260 fs/ocfs2/acl.c:313 __get_acl+0x33a/0x480 fs/posix_acl.c:159 get_inode_acl+0x2b/0x40 fs/posix_acl.c:184 check_acl fs/namei.c:333 [inline] acl_permission_check fs/namei.c:419 [inline] generic_permission+0x509/0x670 fs/namei.c:472 ocfs2_permission+0xeb/0x1a0 fs/ocfs2/file.c:1366 do_inode_permission fs/namei.c:526 [inline] inode_permission+0x317/0x5a0 fs/namei.c:593 may_open+0x10e/0x350 fs/namei.c:3565 do_open fs/namei.c:3973 [inline] path_openat+0x500/0x2ce0 fs/namei.c:4134 do_filp_open+0x1f6/0x430 fs/namei.c:4161 do_sys_openat2+0x117/0x1c0 fs/open.c:1437 do_sys_open fs/open.c:1452 [inline] __do_sys_open fs/open.c:1460 [inline] __se_sys_open fs/open.c:1456 [inline] __x64_sys_open+0x12d/0x1e0 fs/open.c:1456 ... [CAUSE] The lookup helpers only validate the entry position and the name bytes. Once a name matches, ocfs2_xattr_block_get() trusts xe_value_size and memcpy()s that many bytes from inline xattr storage. A local xattr entry is only valid when its inline value both fits the local size limit and stays inside the current xattr block or bucket block. That invariant is never checked for matched local entries, so corrupted metadata can inflate xe_value_size and drive memcpy() past the end of the source block. [FIX] Validate matched local xattr entries before returning them from ocfs2_xattr_find_entry() and ocfs2_find_xe_in_bucket(). Reject entries whose inline value exceeds the local limit or crosses the current block boundary, and route the failure through normal OCFS2 corruption handling. Signed-off-by: ZhengYuan Huang --- diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -237,6 +237,29 @@ return namevalue_size(xe->xe_name_len, value_len); } +static int ocfs2_validate_local_xe(struct inode *inode, + struct ocfs2_xattr_entry *xe, + void *base, + void *end) +{ + char *nameval = base + le16_to_cpu(xe->xe_name_offset); + size_t name_len = OCFS2_XATTR_SIZE(xe->xe_name_len); + u64 value_size = le64_to_cpu(xe->xe_value_size); + + if (value_size > OCFS2_XATTR_INLINE_SIZE) + return ocfs2_error(inode->i_sb, + "Inode %llu has invalid local xattr value size %llu\n", + (unsigned long long)OCFS2_I(inode)->ip_blkno, + (unsigned long long)value_size); + + if (nameval + name_len + value_size > (char *)end) + return ocfs2_error(inode->i_sb, + "Inode %llu has corrupt local xattr value bounds\n", + (unsigned long long)OCFS2_I(inode)->ip_blkno); + + return 0; +} + static int ocfs2_xattr_bucket_get_name_value(struct super_block *sb, struct ocfs2_xattr_header *xh, @@ -1098,7 +1121,7 @@ { struct ocfs2_xattr_entry *entry; size_t name_len; - int i, name_offset, cmp = 1; + int i, name_offset, cmp = 1, ret; if (name == NULL) return -EINVAL; @@ -1121,6 +1144,11 @@ return -EFSCORRUPTED; } cmp = memcmp(name, (xs->base + name_offset), name_len); + if (!cmp && ocfs2_xattr_is_local(entry)) { + ret = ocfs2_validate_local_xe(inode, entry, xs->base, xs->end); + if (ret) + return ret; + } } if (cmp == 0) break; @@ -3790,6 +3818,8 @@ struct ocfs2_xattr_header *xh = bucket_xh(bucket); size_t name_len = strlen(name); struct ocfs2_xattr_entry *xe = NULL; + char *block; + char *block_end; char *xe_name; /* @@ -3821,8 +3851,15 @@ } - xe_name = bucket_block(bucket, block_off) + new_offset; + block = bucket_block(bucket, block_off); + block_end = block + inode->i_sb->s_blocksize; + xe_name = block + new_offset; if (!memcmp(name, xe_name, name_len)) { + if (ocfs2_xattr_is_local(xe)) { + ret = ocfs2_validate_local_xe(inode, xe, block, block_end); + if (ret) + break; + } *xe_index = i; *found = 1; ret = 0; -- 2.43.0