In f2fs_getxattr(), the function lookup_all_xattrs() allocates a 12-byte
(base_size) buffer for an inline extended attribute. However, when
__find_inline_xattr() calls __find_xattr(), it uses the macro
"list_for_each_xattr(entry, addr)", which starts by calling
XATTR_FIRST_ENTRY(addr). This skips a 24-byte struct f2fs_xattr_header
at the beginning of the buffer, causing an immediate out-of-bounds read
in a 12-byte allocation. The subsequent !IS_XATTR_LAST_ENTRY(entry)
check then dereferences memory outside the allocated region, triggering
the slab-out-of bounds read.

This patch prevents the out-of-bounds read by adding a check to bail
out early if inline_size is too small and does not account for the
header plus the 4-byte value that IS_XATTR_LAST_ENTRY reads.

Reported-by: syzbot <syzbot+f5e74075e096e757b...@syzkaller.appspotmail.com>
Closes: https://syzkaller.appspot.com/bug?extid=f5e74075e096e757bdbf
Tested-by: syzbot <syzbot+f5e74075e096e757b...@syzkaller.appspotmail.com>
Tested-by: Qasim Ijaz <qasde...@gmail.com>
Fixes: 388a2a0640e1 ("f2fs: remove redundant sanity check in 
sanity_check_inode()")
Signed-off-by: Qasim Ijaz <qasde...@gmail.com>
---
 fs/f2fs/xattr.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
index 3f3874943679..cf82646bca0e 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -329,6 +329,9 @@ static int lookup_all_xattrs(struct inode *inode, struct 
page *ipage,
        if (!xnid && !inline_size)
                return -ENODATA;
 
+       if (inline_size < sizeof(struct f2fs_xattr_header) + sizeof(__u32))
+               return -ENODATA;
+
        *base_size = XATTR_SIZE(inode) + XATTR_PADDING_SIZE;
        txattr_addr = xattr_alloc(F2FS_I_SB(inode), *base_size, is_inline);
        if (!txattr_addr)
-- 
2.39.5


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to