From nobody Wed Dec 17 21:40:58 2025 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 CFF50220697; Fri, 6 Dec 2024 17:28:51 +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=1733506134; cv=none; b=mQk/5B02Fl3R77uCfWXjMtODBvv3MlWkbzNJaEL3TeiL1vEli94/pVPCJ1LxVS0CeEK2/00/401WsOA2ekG8SJQ04N2feAUS7OgdxVWHyBX/GhIhee2GYswwUYMJIAVJ+ZcaSLfv0v5Jej3BvapGwQS6N+PYVV1TDtfiA6An750= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733506134; c=relaxed/simple; bh=FCFFp4lJ0eHx/aMpS3OCV9F9xnKYBez2NRREyrb7Mls=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=crXpPkRFbD+6amv3MY23rlT703lLyEZW6nVuK7OgMbiAeSd71C7AUpu0sLPkC/keSpGT1qLTZ+ATq9yFt5abEWac5OzUNxg9uUA3oWD2Uro6WAnOmmD6WFPPCh9po+GkzA8pFzEu+UCv0HuZvhdq0LCHIunLrP++4Rzv0zV5hjM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (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=E1pRIEDI; arc=none smtp.client-ip=178.60.130.6 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (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="E1pRIEDI" 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=6iVLZzEIOo2SG6lIQurpFi2Z8md7I09POZIXP4exDHM=; b=E1pRIEDI1wKeFHkrrH/0Foyd1x RNcECO4K/F+4skd09UweOVPubR97tFkqzQQjJJoSl1eCMTiRUJdYtiwR6WvaHweYGjeFivPq3Lb79 h/RqcNqFJD1o5k/almU7x4CcVkZ3aal35J3KXVL4+SY5VtKYf2C/PP/Tn551EImuQg4CxZzYDKwoO UjZ8MZNtmYWSdhJ90K4w1cGFbWbHFN9fzG1MYDB4ISjVqUB5WM2Eqi7av1UKS8K5KFJfUqw5C5gb6 IhdVal6eYLl5xaYlZD8Hd7O36/jMonW5ilg1kJRmE1aacRyGC8n/BHQ/lL4ykg+TnIKMFerT0h5Tg oXydGHYA==; Received: from 179-125-79-245-dinamico.pombonet.net.br ([179.125.79.245] helo=localhost.localdomain) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1tJc8H-00HUmO-2Y; Fri, 06 Dec 2024 18:28:49 +0100 From: Thadeu Lima de Souza Cascardo To: linux-ext4@vger.kernel.org Cc: "Theodore Ts'o" , Andreas Dilger , linux-kernel@vger.kernel.org, kernel-dev@igalia.com, Thadeu Lima de Souza Cascardo Subject: [PATCH 1/5] ext4: inline: remove extra size check when writing data Date: Fri, 6 Dec 2024 14:28:24 -0300 Message-Id: <20241206172828.3219989-2-cascardo@igalia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241206172828.3219989-1-cascardo@igalia.com> References: <20241206172828.3219989-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" ext4_prepare_inline_data which is called right after the removed check has the same check. This avoids extra calls to ext4_get_inode_loc and having to traverse all xattrs in the inode twice for that check. Signed-off-by: Thadeu Lima de Souza Cascardo --- fs/ext4/inline.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 401a224f0956..0611a050668b 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -668,9 +668,6 @@ int ext4_try_to_write_inline_data(struct address_space = *mapping, struct folio *folio; struct ext4_iloc iloc; =20 - if (pos + len > ext4_get_max_inline_size(inode)) - goto convert; - ret =3D ext4_get_inode_loc(inode, &iloc); if (ret) return ret; --=20 2.34.1 From nobody Wed Dec 17 21:40:58 2025 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 D9048220693; Fri, 6 Dec 2024 17:28:53 +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=1733506136; cv=none; b=UfABRAro3CpbGvOZmkLIBU/vM0jg4ITeiuVByFU7C/HHECwuG0fTGNNGhG3JLcoiSbpy3MMpf7EUVZqN7WqFdMnD+OrqV1Vnk+qJbMk6Son/ERT7OQjW2f24v9krndlkS3m1XNJB+h787lmHM0OAWHHsNxJ12UY4oBG/SaOYrz8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733506136; c=relaxed/simple; bh=pHWZa4vK1ZlwFD/lHE6eNlpJdnbNeWot04QpsBn/bQE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=XPG+rhQ9S2Erp6r5sj8OKZmIX3YSUxHwsE5nHEsYp0e5KQkbkgW0yT93YIGJu2QB8oCYeTk9qm8s1GM6MDJSKPEKRmCj0su1lyztnd1DTC+8ZWzIix/f8wq11CAgTbCaWmz5mInN98Q5DBZrW6hxv2GPYZFTW7KsepCFJKC6dvE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (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=LftnPVdM; arc=none smtp.client-ip=178.60.130.6 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (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="LftnPVdM" 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=G7aF1n7cH8I2dw6cg9IiqZOJN473ZcdDet5KDFTx97w=; b=LftnPVdMUxF2ArEa1LcLttfVwl G3XIZNndG/B2Ojua4U2B1edSFQaSXHa6xEP3zW2Qq+IY+iXD+42LQ9y8jQoJ0H5fKAc3rtFZr203O gXvRMnVk9Xu7cJexe4RhQd/ZgLlCrSR9DjkxxooSC+J+yV9gMBtDPOACfYEwdGie37jf8iLtYhQ/H TfGTVR4ta5U3Kf30bozBm9i5tU6IqW8oROvaWB5YdohbtFJs8RC2edn2jndiHmozIIwfBAyJlOYAf PXBxrgqUvARAYWWnc+2o/7ZLWPgTaOUW6qe6InkGudZiR4wUUt1jyx6DMXjphHOJc6HAFCuJ58Hbb o3AttEZQ==; Received: from 179-125-79-245-dinamico.pombonet.net.br ([179.125.79.245] helo=localhost.localdomain) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1tJc8J-00HUmO-GJ; Fri, 06 Dec 2024 18:28:51 +0100 From: Thadeu Lima de Souza Cascardo To: linux-ext4@vger.kernel.org Cc: "Theodore Ts'o" , Andreas Dilger , linux-kernel@vger.kernel.org, kernel-dev@igalia.com, Thadeu Lima de Souza Cascardo Subject: [PATCH 2/5] ext4: inline: use cached i_inline_size instead of e_value_size Date: Fri, 6 Dec 2024 14:28:25 -0300 Message-Id: <20241206172828.3219989-3-cascardo@igalia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241206172828.3219989-1-cascardo@igalia.com> References: <20241206172828.3219989-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" i_inline_size caches the total size of the inline data, it is always EXT4_MIN_INLINE_DATA_SIZE plus the size of the system.data xattr value. This avoids looking up for the entry again, which allows i_inline_off to be used to point directly to the inline data. Signed-off-by: Thadeu Lima de Souza Cascardo --- fs/ext4/inline.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 0611a050668b..b49cfcadbd36 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -80,10 +80,8 @@ static int get_max_inline_xattr_value_size(struct inode = *inode, ((void *)entry - (void *)IFIRST(header)) - sizeof(__u32); =20 if (EXT4_I(inode)->i_inline_off) { - entry =3D (struct ext4_xattr_entry *) - ((void *)raw_inode + EXT4_I(inode)->i_inline_off); - - free +=3D EXT4_XATTR_SIZE(le32_to_cpu(entry->e_value_size)); + free +=3D EXT4_I(inode)->i_inline_size - + EXT4_MIN_INLINE_DATA_SIZE; goto out; } =20 --=20 2.34.1 From nobody Wed Dec 17 21:40:58 2025 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 0D1C41FFC73; Fri, 6 Dec 2024 17:28: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=1733506139; cv=none; b=DdcMYNiDEQRjZYe+Mj/M22jFZSAkewhFDkCoSdPxMFxO2ejYGxLEcRKjhmM55y9ZoGNc5WwWCZj2ZMrAOrcOdkbH0yW4f23zZbGGkysrXP1QZPukQ88AZH9SXbHl4NkqFTHtphcDSQmvlUEtVmZru1iruhi+jjpgNtpzVnxuVJo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733506139; c=relaxed/simple; bh=D6bPQcNYukDItmgpy9dzRSBUjrFOdsEYvJIaD7mY9cM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=glxM3OBED8f+6C6bNM4hiq26kiSj+rNNltZ5QqTJTxOCDK6VpMJGTQWVGN7JGE+DU3a3Evx5VzFgWCDlKU8g0G+m1UMSpxX5kaQSecjcZEJ47iJEx9dyYKQDATjvXCzzBgJOPTJRyQ9T3Cqc68CBEhTSTZK90Lrm8ff16nlSINo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (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=Wug027aN; arc=none smtp.client-ip=178.60.130.6 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (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="Wug027aN" 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=8oIpgUOrCw7wy276EldFAK/fTJ+Aor2rT3kshxjjKSg=; b=Wug027aNdqcQK1Pp7N1WitByvf JnjlqkbZHzpYJxIWpyWVfJtP5kho8c8AghRzg5VgHfVd935TGui7MsjOYdCJlIB2oOsYYELQcDqqh OR4eR7ilxn2aLtmsxYX/H1sSOEyYbkGAf6N3BChfvSkKl2tAkvx+RF6wP0ej0QYw6a2EGYNLxYLFY 8fK4ub4u8i2f2xycTdar4DyDrkva29doRYucClwrX2SrIsmfGIFM/w1rvwxzhUKB0D708JRAdVyl4 R61iXWyWK64tFUKsECa0/pIQQxWNrODR8N6qaU5n6ah99oRaXOzPIYyH9398fB5QMQYg/rrBxyO0K G7YnZ4Ig==; Received: from 179-125-79-245-dinamico.pombonet.net.br ([179.125.79.245] helo=localhost.localdomain) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1tJc8M-00HUmO-6y; Fri, 06 Dec 2024 18:28:54 +0100 From: Thadeu Lima de Souza Cascardo To: linux-ext4@vger.kernel.org Cc: "Theodore Ts'o" , Andreas Dilger , linux-kernel@vger.kernel.org, kernel-dev@igalia.com, Thadeu Lima de Souza Cascardo Subject: [PATCH 3/5] ext4: introduce wrapper to read data from inode Date: Fri, 6 Dec 2024 14:28:26 -0300 Message-Id: <20241206172828.3219989-4-cascardo@igalia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241206172828.3219989-1-cascardo@igalia.com> References: <20241206172828.3219989-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" ext4_read_inline_data callers will usually follow similar steps, fetching inode block, parsing xattrs, allocating a buffer, and copying the data. Put it all under the same wrapper and have most callers use it. Some callers allocate their own buffers, so allow those to be used. The exception here is ext4_convert_inline_data. This avoids OOB when reading inline dir and other potential bugs. When reading inline 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. The wrapper function takes care of checking xattrs are still valid. Signed-off-by: Thadeu Lima de Souza Cascardo --- fs/ext4/inline.c | 110 +++++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 51 deletions(-) diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index b49cfcadbd36..c3d2fcae6191 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -212,6 +212,51 @@ static int ext4_read_inline_data(struct inode *inode, = void *buffer, return cp_len; } =20 +static int ext4_read_inline_data_from_inode(struct inode *inode, void **bu= ffer, + size_t *len, + struct ext4_iloc *iloc, + 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; + + ret =3D ext4_get_inode_loc(inode, &is.iloc); + if (ret) + goto out; + + ret =3D ext4_xattr_ibody_find(inode, &i, &is); + if (ret) + goto out; + + if (!ext4_has_inline_data(inode)) { + if (has_inline_data) + *has_inline_data =3D 0; + goto out; + } + + if (!*len) + *len =3D ext4_get_inline_size(inode); + if (!*buffer) { + *buffer =3D kmalloc(*len, GFP_NOFS); + if (!*buffer) { + ret =3D -ENOMEM; + goto out; + } + } + + ret =3D ext4_read_inline_data(inode, *buffer, *len, &is.iloc); + +out: + *iloc =3D is.iloc; + return ret; +} + /* * write the buffer to the inline inode. * If 'create' is set, we don't need to do the extra copy in the xattr @@ -492,14 +537,10 @@ static int ext4_read_inline_folio(struct inode *inode= , struct folio *folio) goto out; } =20 - ret =3D ext4_get_inode_loc(inode, &iloc); - if (ret) - goto out; - len =3D min_t(size_t, ext4_get_inline_size(inode), i_size_read(inode)); BUG_ON(len > PAGE_SIZE); kaddr =3D kmap_local_folio(folio, 0); - ret =3D ext4_read_inline_data(inode, kaddr, len, &iloc); + ret =3D ext4_read_inline_data_from_inode(inode, &kaddr, &len, &iloc, NULL= ); kaddr =3D folio_zero_tail(folio, len, kaddr + len); kunmap_local(kaddr); folio_mark_uptodate(folio); @@ -1333,32 +1374,16 @@ int ext4_inlinedir_to_tree(struct file *dir_file, int pos; struct ext4_dir_entry_2 *de; struct inode *inode =3D file_inode(dir_file); - int ret, inline_size =3D 0; + int ret; + size_t inline_size =3D 0; struct ext4_iloc iloc; void *dir_buf =3D NULL; struct ext4_dir_entry_2 fake; struct fscrypt_str tmp_str; =20 - ret =3D ext4_get_inode_loc(inode, &iloc); - if (ret) - return ret; - down_read(&EXT4_I(inode)->xattr_sem); - if (!ext4_has_inline_data(inode)) { - up_read(&EXT4_I(inode)->xattr_sem); - *has_inline_data =3D 0; - goto out; - } - - inline_size =3D ext4_get_inline_size(inode); - dir_buf =3D kmalloc(inline_size, GFP_NOFS); - if (!dir_buf) { - ret =3D -ENOMEM; - up_read(&EXT4_I(inode)->xattr_sem); - goto out; - } - - ret =3D ext4_read_inline_data(inode, dir_buf, inline_size, &iloc); + ret =3D ext4_read_inline_data_from_inode(inode, &dir_buf, &inline_size, + &iloc, has_inline_data); up_read(&EXT4_I(inode)->xattr_sem); if (ret < 0) goto out; @@ -1452,32 +1477,16 @@ int ext4_read_inline_dir(struct file *file, struct ext4_dir_entry_2 *de; struct super_block *sb; struct inode *inode =3D file_inode(file); - int ret, inline_size =3D 0; + int ret; + size_t inline_size =3D 0; struct ext4_iloc iloc; void *dir_buf =3D NULL; int dotdot_offset, dotdot_size, extra_offset, extra_size; struct dir_private_info *info =3D file->private_data; =20 - ret =3D ext4_get_inode_loc(inode, &iloc); - if (ret) - return ret; - down_read(&EXT4_I(inode)->xattr_sem); - if (!ext4_has_inline_data(inode)) { - up_read(&EXT4_I(inode)->xattr_sem); - *has_inline_data =3D 0; - goto out; - } - - inline_size =3D ext4_get_inline_size(inode); - dir_buf =3D kmalloc(inline_size, GFP_NOFS); - if (!dir_buf) { - ret =3D -ENOMEM; - up_read(&EXT4_I(inode)->xattr_sem); - goto out; - } - - ret =3D ext4_read_inline_data(inode, dir_buf, inline_size, &iloc); + ret =3D ext4_read_inline_data_from_inode(inode, &dir_buf, &inline_size, + &iloc, has_inline_data); up_read(&EXT4_I(inode)->xattr_sem); if (ret < 0) goto out; @@ -1577,26 +1586,25 @@ int ext4_read_inline_dir(struct file *file, void *ext4_read_inline_link(struct inode *inode) { struct ext4_iloc iloc; - int ret, inline_size; + int ret; + size_t inline_size; void *link; =20 - ret =3D ext4_get_inode_loc(inode, &iloc); - if (ret) - return ERR_PTR(ret); - ret =3D -ENOMEM; inline_size =3D ext4_get_inline_size(inode); link =3D kmalloc(inline_size + 1, GFP_NOFS); if (!link) goto out; =20 - ret =3D ext4_read_inline_data(inode, link, inline_size, &iloc); + down_read(&EXT4_I(inode)->xattr_sem); + ret =3D ext4_read_inline_data_from_inode(inode, &link, &inline_size, &ilo= c, NULL); if (ret < 0) { kfree(link); goto out; } nd_terminate_link(link, inode->i_size, ret); out: + up_read(&EXT4_I(inode)->xattr_sem); if (ret < 0) link =3D ERR_PTR(ret); brelse(iloc.bh); --=20 2.34.1 From nobody Wed Dec 17 21:40:58 2025 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 E7214204572; Fri, 6 Dec 2024 17:28:58 +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=1733506141; cv=none; b=JTlrKRhHOxMxsntFmzL3WNdZGZuq6Xb7bkiiBZY+1Bh2unZC20H/5EiTNj42OwBdxISYHD9xVYKW8rvUNbcMWsvpXadyVQMeAv8HR3qACmunXbdClsa/nIAziQIQdqxtawuo2J84BKrJfsGVzlJPzU6b0PTXy+P3ivCiCoTwhwk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733506141; c=relaxed/simple; bh=vw/WbYE8RrUcs04aujsMJJvqGf3y5OIp03ii0Db40eM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tEzUCmApFsQF6X4+TbTYKeQ4BK18Yp82d73a4dLpvDfCdsyUwNCGsoJZ5qQpDWHDUXUEmDonCRo/4vnsOvYYy1kV/L/QPo0/brKaVSFLshw2nzPfZOJ5egLR/raJP8yOygnbRrsWDkc13K8Rb39nGb0b8a0IIyUeHlBSj7LRP2U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (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=pd8VBJvf; arc=none smtp.client-ip=178.60.130.6 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (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="pd8VBJvf" 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=ye2tcP/e/A7fCZi3F9QVa918q4hBAxGAnVtC03cUxcU=; b=pd8VBJvf1p50UapWyRtcnqX7Hq VTOGaNCjFYyVYpEcBWSppbSnPVcBYEUxKGA1Xs4B3VcIBo2Ozt91KO68gkCMl3wJIorQScI0EVSws XL5KGNxo49kbjeytbOHNw9b75kJKVvSRk6uFFHpwpinQk1Y/nl1xKrW2gw5SJ2OcVoa5eLUnLVuBw GSRBIevi7nZeG0II3ocmlTi3TbN84m7WIq3Fq6dVZQ8Yn7dK0bVG2hJqKZZEKlvNBhwL9b+cp8i0J +qYJzGKuANyRNFbcdr3oSpGAtib2su/WZJaqoN+2IdZQms0iIRo/ZNKdxNe487ot1uxIv6YaG8Uim NfrnfiVg==; Received: from 179-125-79-245-dinamico.pombonet.net.br ([179.125.79.245] helo=localhost.localdomain) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1tJc8O-00HUmO-OL; Fri, 06 Dec 2024 18:28:57 +0100 From: Thadeu Lima de Souza Cascardo To: linux-ext4@vger.kernel.org Cc: "Theodore Ts'o" , Andreas Dilger , linux-kernel@vger.kernel.org, kernel-dev@igalia.com, Thadeu Lima de Souza Cascardo Subject: [PATCH 4/5] ext4: add a wrapper to update i_inline_off and i_inline_size Date: Fri, 6 Dec 2024 14:28:27 -0300 Message-Id: <20241206172828.3219989-5-cascardo@igalia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241206172828.3219989-1-cascardo@igalia.com> References: <20241206172828.3219989-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" They were updated in three different places, with slight variations. This will make it easier to change them. Signed-off-by: Thadeu Lima de Souza Cascardo --- fs/ext4/inline.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index c3d2fcae6191..cd2014af9823 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -129,6 +129,15 @@ int ext4_get_max_inline_size(struct inode *inode) return max_inline_size + EXT4_MIN_INLINE_DATA_SIZE; } =20 +static void ext4_update_inline_off_size(struct inode *inode, + struct ext4_inode *raw_inode, + struct ext4_xattr_entry *entry) +{ + EXT4_I(inode)->i_inline_off =3D (u16)((void *)entry - (void *)raw_inode); + EXT4_I(inode)->i_inline_size =3D EXT4_MIN_INLINE_DATA_SIZE + + le32_to_cpu(entry->e_value_size); +} + /* * this function does not take xattr_sem, which is OK because it is * currently only used in a code path coming form ext4_iget, before @@ -163,10 +172,8 @@ int ext4_find_inline_data_nolock(struct inode *inode) error =3D -EFSCORRUPTED; goto out; } - EXT4_I(inode)->i_inline_off =3D (u16)((void *)is.s.here - - (void *)ext4_raw_inode(&is.iloc)); - EXT4_I(inode)->i_inline_size =3D EXT4_MIN_INLINE_DATA_SIZE + - le32_to_cpu(is.s.here->e_value_size); + ext4_update_inline_off_size(inode, ext4_raw_inode(&is.iloc), + is.s.here); } out: brelse(is.iloc.bh); @@ -354,9 +361,8 @@ static int ext4_create_inline_data(handle_t *handle, memset((void *)ext4_raw_inode(&is.iloc)->i_block, 0, EXT4_MIN_INLINE_DATA_SIZE); =20 - EXT4_I(inode)->i_inline_off =3D (u16)((void *)is.s.here - - (void *)ext4_raw_inode(&is.iloc)); - EXT4_I(inode)->i_inline_size =3D len + EXT4_MIN_INLINE_DATA_SIZE; + ext4_update_inline_off_size(inode, ext4_raw_inode(&is.iloc), is.s.here); + ext4_clear_inode_flag(inode, EXT4_INODE_EXTENTS); ext4_set_inode_flag(inode, EXT4_INODE_INLINE_DATA); get_bh(is.iloc.bh); @@ -420,10 +426,7 @@ static int ext4_update_inline_data(handle_t *handle, s= truct inode *inode, if (error) goto out; =20 - EXT4_I(inode)->i_inline_off =3D (u16)((void *)is.s.here - - (void *)ext4_raw_inode(&is.iloc)); - EXT4_I(inode)->i_inline_size =3D EXT4_MIN_INLINE_DATA_SIZE + - le32_to_cpu(is.s.here->e_value_size); + ext4_update_inline_off_size(inode, ext4_raw_inode(&is.iloc), is.s.here); ext4_set_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA); get_bh(is.iloc.bh); error =3D ext4_mark_iloc_dirty(handle, inode, &is.iloc); --=20 2.34.1 From nobody Wed Dec 17 21:40:58 2025 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 30C4720459D; Fri, 6 Dec 2024 17:29:01 +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=1733506143; cv=none; b=Sd043ymhlW4yPBSPighCg4zGPH/G/z11AoTsgpMTpcq1ST5X7sdmYA0Hvb9JIvTDYju3h+8V9VTMgoZkYuliaw3UO2vROtWMQOrQGzYuD0y3UO6bL8vnF90tBILdPZBa+YKPJ7jCE8o2zUMGGHRqdzB6i7y2YyD+2J0xLUNl4sM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1733506143; c=relaxed/simple; bh=b080vVlV8tHb90OsSrK+IEUUi08J1cDRUHSL6tuv3e0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=law/EZD3Mpci47/m0Fs6mIKcsMPlAkzP7C5rda3JTlgw7pBKYy8+ajvqcHlSK4xepDUP9y2ZU81e5NRrz6JMjEfllb3nxFcmE8afR2PdO7RMRi/raPrKZnIOgfLi7GuKxV4aIFV6JmVAt2P9AhtN3FwcyYStxfvl3AwXIUVoOtY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (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=sMfTboRC; arc=none smtp.client-ip=178.60.130.6 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (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="sMfTboRC" 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=rjUd2AM2/YEWsLZUV6glYoJjEHrghXkYN6js8vSJ7uo=; b=sMfTboRCamx/JCedNhTDecnvGk dDC6Czow+OToi2tF2XPKxCVgFjRlSn6bXqou0K6D43EXMvb0epseRAq8RtO4gC7yOJJUAWcccu3er FeuTe/Lgrpmqgn39KCvkiABBNmxiRbw+u5hhKdOxl5N33Ua6AUeGus6lv21P2H8kmic0wySU7LZul vVXJnsg4UMPYKoWwQ8qrEy0KMKIEWsUqpZKXUIm7Q4Rl33TC2JpE1hiZ0EIfDueBBDQnNW7Xlqb4p iQLM7KePMRivGWx33xl2PBUHYRhlyIETsaxyxZSKusxRNPVNtrueZpz14nUswFowfHC8bijq0Pu87 dvmBeuAA==; Received: from 179-125-79-245-dinamico.pombonet.net.br ([179.125.79.245] helo=localhost.localdomain) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1tJc8R-00HUmO-Gl; Fri, 06 Dec 2024 18:29:00 +0100 From: Thadeu Lima de Souza Cascardo To: linux-ext4@vger.kernel.org Cc: "Theodore Ts'o" , Andreas Dilger , linux-kernel@vger.kernel.org, kernel-dev@igalia.com, Thadeu Lima de Souza Cascardo Subject: [PATCH 5/5] ext4: make i_inline_off point to data Date: Fri, 6 Dec 2024 14:28:28 -0300 Message-Id: <20241206172828.3219989-6-cascardo@igalia.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241206172828.3219989-1-cascardo@igalia.com> References: <20241206172828.3219989-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" Instead of having i_inline_off pointing to the xattr entry, make it point directly to the value offset. That will allow e_value_offs to be ignored, preventing many issues where it might have changed on disk after being validated. This prevents many potential out-of-bound accesses. Signed-off-by: Thadeu Lima de Souza Cascardo --- fs/ext4/inline.c | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index cd2014af9823..92e300c3f873 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -133,7 +133,12 @@ static void ext4_update_inline_off_size(struct inode *= inode, struct ext4_inode *raw_inode, struct ext4_xattr_entry *entry) { - EXT4_I(inode)->i_inline_off =3D (u16)((void *)entry - (void *)raw_inode); + struct ext4_xattr_ibody_header *header; + void *off; + + header =3D IHDR(inode, raw_inode); + off =3D (void *)IFIRST(header) + le16_to_cpu(entry->e_value_offs); + EXT4_I(inode)->i_inline_off =3D (u16)(off - (void *)raw_inode); EXT4_I(inode)->i_inline_size =3D EXT4_MIN_INLINE_DATA_SIZE + le32_to_cpu(entry->e_value_size); } @@ -184,8 +189,6 @@ static int ext4_read_inline_data(struct inode *inode, v= oid *buffer, unsigned int len, struct ext4_iloc *iloc) { - struct ext4_xattr_entry *entry; - struct ext4_xattr_ibody_header *header; int cp_len =3D 0; struct ext4_inode *raw_inode; =20 @@ -205,14 +208,7 @@ static int ext4_read_inline_data(struct inode *inode, = void *buffer, if (!len) goto out; =20 - header =3D IHDR(inode, raw_inode); - entry =3D (struct ext4_xattr_entry *)((void *)raw_inode + - EXT4_I(inode)->i_inline_off); - len =3D min_t(unsigned int, len, - (unsigned int)le32_to_cpu(entry->e_value_size)); - - memcpy(buffer, - (void *)IFIRST(header) + le16_to_cpu(entry->e_value_offs), len); + memcpy(buffer, (void *)raw_inode + EXT4_I(inode)->i_inline_off, len); cp_len +=3D len; =20 out: @@ -273,8 +269,6 @@ static int ext4_read_inline_data_from_inode(struct inod= e *inode, void **buffer, static void ext4_write_inline_data(struct inode *inode, struct ext4_iloc *= iloc, void *buffer, loff_t pos, unsigned int len) { - struct ext4_xattr_entry *entry; - struct ext4_xattr_ibody_header *header; struct ext4_inode *raw_inode; int cp_len =3D 0; =20 @@ -301,11 +295,8 @@ static void ext4_write_inline_data(struct inode *inode= , struct ext4_iloc *iloc, return; =20 pos -=3D EXT4_MIN_INLINE_DATA_SIZE; - header =3D IHDR(inode, raw_inode); - entry =3D (struct ext4_xattr_entry *)((void *)raw_inode + - EXT4_I(inode)->i_inline_off); =20 - memcpy((void *)IFIRST(header) + le16_to_cpu(entry->e_value_offs) + pos, + memcpy((void *)raw_inode + EXT4_I(inode)->i_inline_off + pos, buffer, len); } =20 @@ -1085,16 +1076,12 @@ static int ext4_add_dirent_to_inline(handle_t *hand= le, static void *ext4_get_inline_xattr_pos(struct inode *inode, struct ext4_iloc *iloc) { - struct ext4_xattr_entry *entry; - struct ext4_xattr_ibody_header *header; + struct ext4_inode *raw_inode; =20 BUG_ON(!EXT4_I(inode)->i_inline_off); =20 - header =3D IHDR(inode, ext4_raw_inode(iloc)); - entry =3D (struct ext4_xattr_entry *)((void *)ext4_raw_inode(iloc) + - EXT4_I(inode)->i_inline_off); - - return (void *)IFIRST(header) + le16_to_cpu(entry->e_value_offs); + raw_inode =3D ext4_raw_inode(iloc); + return (void *)raw_inode + EXT4_I(inode)->i_inline_off; } =20 /* Set the final de to cover the whole block. */ --=20 2.34.1