Commit 2ab62234 authored by Darrick J. Wong's avatar Darrick J. Wong Committed by Greg Kroah-Hartman

xfs: don't overflow xattr listent buffer

commit 3b50086f upstream.

For VFS listxattr calls, xfs_xattr_put_listent calls
__xfs_xattr_put_listent twice if it sees an attribute
"trusted.SGI_ACL_FILE": once for that name, and again for
"system.posix_acl_access".  Unfortunately, if we happen to run out of
buffer space while emitting the first name, we set count to -1 (so that
we can feed ERANGE to the caller).  The second invocation doesn't check that
the context parameters make sense and overwrites the byte before the
buffer, triggering a KASAN report:

==================================================================
BUG: KASAN: slab-out-of-bounds in strncpy+0xb3/0xd0
Write of size 1 at addr ffff88807fbd317f by task syz/1113

CPU: 3 PID: 1113 Comm: syz Not tainted 5.0.0-rc6-xfsx #rc6
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.10.2-1ubuntu1 04/01/2014
Call Trace:
 dump_stack+0xcc/0x180
 print_address_description+0x6c/0x23c
 kasan_report.cold.3+0x1c/0x35
 strncpy+0xb3/0xd0
 __xfs_xattr_put_listent+0x1a9/0x2c0 [xfs]
 xfs_attr_list_int_ilocked+0x11af/0x1800 [xfs]
 xfs_attr_list_int+0x20c/0x2e0 [xfs]
 xfs_vn_listxattr+0x225/0x320 [xfs]
 listxattr+0x11f/0x1b0
 path_listxattr+0xbd/0x130
 do_syscall_64+0x139/0x560

While we're at it we add an assert to the other put_listent to avoid
this sort of thing ever happening to the attrlist_by_handle code.
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Suggested-by: default avatarAmir Goldstein <amir73il@gmail.com>
Reviewed-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarLuis Chamberlain <mcgrof@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 1dc8b13c
...@@ -555,6 +555,7 @@ xfs_attr_put_listent( ...@@ -555,6 +555,7 @@ xfs_attr_put_listent(
attrlist_ent_t *aep; attrlist_ent_t *aep;
int arraytop; int arraytop;
ASSERT(!context->seen_enough);
ASSERT(!(context->flags & ATTR_KERNOVAL)); ASSERT(!(context->flags & ATTR_KERNOVAL));
ASSERT(context->count >= 0); ASSERT(context->count >= 0);
ASSERT(context->count < (ATTR_MAX_VALUELEN/8)); ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
......
...@@ -129,6 +129,9 @@ __xfs_xattr_put_listent( ...@@ -129,6 +129,9 @@ __xfs_xattr_put_listent(
char *offset; char *offset;
int arraytop; int arraytop;
if (context->count < 0 || context->seen_enough)
return;
if (!context->alist) if (!context->alist)
goto compute_size; goto compute_size;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment