From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 2EC0E409608 for ; Tue, 16 Jun 2026 08:55:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781600106; cv=none; b=enrp1mJR0B1uxTiTjFJaooc+2vNIAiH2W0RwS5gdep06s8V0rJDadXKzC7qFRhssVkYm7EZTvOuy5seCfUTF3p+rvb1R9Brt4ePe+zdLte6eWQsAziXRN8UoPl9rHXrAYLZLud7xlthSySg9FD7ge6RxuvB1WxZv+/q7ADyYkxI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781600106; c=relaxed/simple; bh=kw6tJrfeDW5i8a7p32ouwWiNVKtTrZe7Kns9ANS0R64=; h=Message-ID:Date:MIME-Version:Cc:Subject:To:References:From: In-Reply-To:Content-Type; b=faxbgoMR9bI6ceJ/TIQaAK/XmVSNVbwUbiPD1wnWVdJW0z0cFBD0G7waOWXT3MVh8xhfGOJxh07IdOoUeUd/wMvvTvwuxTTGoSGzoacPbozCZ24JudLcgk7SN2hq/hKynJGDy+OTpVpM13FPLVkyNPM5ughRBEHnW2SDK7OATnE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Onlv5oOi; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Onlv5oOi" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BF5691F000E9; Tue, 16 Jun 2026 08:55:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1781600104; bh=GLH8stHXoCSzvmMoSuouXVXmnZLFHxqXEnOUUBsu2w0=; h=Date:Cc:Subject:To:References:From:In-Reply-To; b=Onlv5oOib2oLQlgWoVfzpnt7aqIuxb0EkgTVv8u6Yfpy7ZTi2mvU7EgTYfEGOUnFQ sa2aV/dFGhCOr88+3QkiYOv90F5A9Ijx+P0dsjCRVZlsBA6A9ZU7l/joI2qwIPlZp6 sDFFuQptsgoBZCl8IxsOjeEQhZh8JKF1bxrMCoydbrRTGZpptBb7iSbnYV9REBrXkF TR2Jxj/2Fmh9Xc5xmGO8/042a5nBwrV25NS8sm4n3fGRh/uhjp9HAX0g9klaSzYGiO RYDlXeRbxTXK57FbelnPu6LKyqvtaDStosXnU9AoaXHwaC5fXN1m1mYF5HiMIRK+i4 muNj3fXWEljvA== Message-ID: <4e9c61d4-c942-4291-96cb-02455da05257@kernel.org> Date: Tue, 16 Jun 2026 16:55:01 +0800 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Cc: chao@kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org Subject: Re: [PATCH] f2fs: bound i_inline_xattr_size for non-inline-xattr inodes To: hexlabsecurity@proton.me, Jaegeuk Kim References: <20260611-b4-disp-155e8807-v1-1-5d14dcc72b15@proton.me> Content-Language: en-US From: Chao Yu In-Reply-To: <20260611-b4-disp-155e8807-v1-1-5d14dcc72b15@proton.me> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit On 6/12/26 12:00, Bryam Vargas via B4 Relay wrote: > From: Bryam Vargas > > When the flexible_inline_xattr feature is enabled, do_read_inode() loads > the on-disk i_inline_xattr_size unconditionally: > > if (f2fs_sb_has_flexible_inline_xattr(sbi)) > fi->i_inline_xattr_size = le16_to_cpu(ri->i_inline_xattr_size); > > but sanity_check_inode() only range-checks it when the inode also has the > FI_INLINE_XATTR flag set. An inode that carries an inline dentry or inline > data but not FI_INLINE_XATTR -- the normal layout for an inline > directory -- therefore keeps a fully attacker-controlled > i_inline_xattr_size from a crafted image. > > get_inline_xattr_addrs() returns that value with no flag gating, so it > feeds the inode geometry: > > MAX_INLINE_DATA() = 4 * (CUR_ADDRS_PER_INODE - i_inline_xattr_size - 1) > NR_INLINE_DENTRY() = MAX_INLINE_DATA() * BITS_PER_BYTE / (...) > addrs_per_page() = CUR_ADDRS_PER_INODE - i_inline_xattr_size > > A large i_inline_xattr_size drives MAX_INLINE_DATA() and NR_INLINE_DENTRY() > negative, so make_dentry_ptr_inline() sets d->max (int) to a negative > value. The inline directory walk then compares an unsigned long bit_pos > against that negative d->max, which is promoted to a huge unsigned bound, > and reads far past the inline area: > > while (bit_pos < d->max) /* fs/f2fs/dir.c */ > ... test_bit_le(bit_pos, d->bitmap) / d->dentry[bit_pos] ... > > Mounting a crafted image and reading such a directory triggers an > out-of-bounds read in f2fs_fill_dentries(); the same underflow also > corrupts ADDRS_PER_INODE for regular files. > > Validate i_inline_xattr_size against MAX_INLINE_XATTR_SIZE whenever the > flexible_inline_xattr feature is enabled -- i.e. whenever the value is > loaded from disk and consumed -- and keep the lower MIN_INLINE_XATTR_SIZE > bound gated on inodes that actually carry an inline xattr, so legitimate > inodes with i_inline_xattr_size == 0 are still accepted. > > Fixes: 6afc662e68b5 ("f2fs: support flexible inline xattr size") > Cc: stable@vger.kernel.org > Signed-off-by: Bryam Vargas Reviewed-by: Chao Yu Thanks,