All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH -v2 1/2] ext4: add bounds checking in get_max_inline_xattr_value_size()
@ 2023-05-13  5:12 Theodore Ts'o
  2023-05-13  5:12 ` [PATCH -v2 2/2] ext4: bail out of ext4_xattr_ibody_get() fails for any reason Theodore Ts'o
  0 siblings, 1 reply; 2+ messages in thread
From: Theodore Ts'o @ 2023-05-13  5:12 UTC (permalink / raw)
  Cc: Ext4 Developers List, Theodore Ts'o, syzbot+1966db24521e5f6e23f7

Normally the extended attributes in the inode body would have been
checked when the inode is first opened, but if someone is writing to
the block device while the file system is mounted, it's possible for
the inode table to get corrupted.  Add bounds checking to avoid
reading beyond the end of allocated memory if this happens.

Reported-by: syzbot+1966db24521e5f6e23f7@syzkaller.appspotmail.com
Link: https://syzkaller.appspot.com/bug?extid=1966db24521e5f6e23f7
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---

Changes from -v1: none

 fs/ext4/inline.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index d3dfc51a43c5..f47adb284e90 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -34,6 +34,7 @@ static int get_max_inline_xattr_value_size(struct inode *inode,
 	struct ext4_xattr_ibody_header *header;
 	struct ext4_xattr_entry *entry;
 	struct ext4_inode *raw_inode;
+	void *end;
 	int free, min_offs;
 
 	if (!EXT4_INODE_HAS_XATTR_SPACE(inode))
@@ -57,14 +58,23 @@ static int get_max_inline_xattr_value_size(struct inode *inode,
 	raw_inode = ext4_raw_inode(iloc);
 	header = IHDR(inode, raw_inode);
 	entry = IFIRST(header);
+	end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
 
 	/* Compute min_offs. */
-	for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
+	while (!IS_LAST_ENTRY(entry)) {
+		void *next = EXT4_XATTR_NEXT(entry);
+
+		if (next >= end) {
+			EXT4_ERROR_INODE(inode,
+					 "corrupt xattr in inline inode");
+			return 0;
+		}
 		if (!entry->e_value_inum && entry->e_value_size) {
 			size_t offs = le16_to_cpu(entry->e_value_offs);
 			if (offs < min_offs)
 				min_offs = offs;
 		}
+		entry = next;
 	}
 	free = min_offs -
 		((void *)entry - (void *)IFIRST(header)) - sizeof(__u32);
-- 
2.31.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH -v2 2/2] ext4: bail out of ext4_xattr_ibody_get() fails for any reason
  2023-05-13  5:12 [PATCH -v2 1/2] ext4: add bounds checking in get_max_inline_xattr_value_size() Theodore Ts'o
@ 2023-05-13  5:12 ` Theodore Ts'o
  0 siblings, 0 replies; 2+ messages in thread
From: Theodore Ts'o @ 2023-05-13  5:12 UTC (permalink / raw)
  Cc: Ext4 Developers List, Theodore Ts'o

If ext4_update_inline_data() fails for any reason, it's best if we
just fail as opposed to stumbling on, especially if the failure is
EFSCORRUPTED.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---

Changes from -v1: fixed error check to be for negative values

 fs/ext4/inline.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index f47adb284e90..5854bd5a3352 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -360,7 +360,7 @@ static int ext4_update_inline_data(handle_t *handle, struct inode *inode,
 
 	error = ext4_xattr_ibody_get(inode, i.name_index, i.name,
 				     value, len);
-	if (error == -ENODATA)
+	if (error < 0)
 		goto out;
 
 	BUFFER_TRACE(is.iloc.bh, "get_write_access");
-- 
2.31.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-05-13  5:12 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-13  5:12 [PATCH -v2 1/2] ext4: add bounds checking in get_max_inline_xattr_value_size() Theodore Ts'o
2023-05-13  5:12 ` [PATCH -v2 2/2] ext4: bail out of ext4_xattr_ibody_get() fails for any reason Theodore Ts'o

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.