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