The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH] f2fs: validate ACL entry sizes before parsing
@ 2026-05-11  7:08 Zhang Cen
  0 siblings, 0 replies; only message in thread
From: Zhang Cen @ 2026-05-11  7:08 UTC (permalink / raw)
  To: Jaegeuk Kim, Chao Yu
  Cc: linux-f2fs-devel, linux-kernel, zerocling0077, 2045gemini,
	Zhang Cen

f2fs_acl_from_disk() parses disk-provided POSIX ACL xattrs by first
computing an entry count from the total xattr size and then walking the
records according to each entry tag.  The walk must prove that the next
short entry header is present before reading e_tag and e_perm, and that a
full entry is present before reading e_id for ACL_USER or ACL_GROUP.

The current code only rejects entry pointers that are strictly past the
end of the xattr buffer.  A malformed ACL can make the tag-driven walk
land exactly at the end while the size-derived count still has entries
left.  The next iteration then reads e_tag/e_perm one entry past the
supplied ACL value.  Sanitized testing on the affected tree reported
slab-out-of-bounds reads in __f2fs_get_acl() from ACL retrieval paths,
with the read address immediately past a 20-byte ACL buffer.

Reject malformed ACLs before each dereference by checking that the short
entry header fits at the start of every iteration, and checking that a
full entry fits before consuming e_id for ACL_USER and ACL_GROUP.  This
keeps valid ACLs unchanged while returning -EINVAL for truncated or
width-inconsistent ACL xattr values.

Sanitizer validation reported:
KASAN slab-out-of-bounds in __f2fs_get_acl()
Read of size 2
Call trace:
  dump_stack_lvl() (?:?)
  print_address_description() (mm/kasan/report.c:373)
  __f2fs_get_acl() (fs/f2fs/acl.c:169)
  print_report() (?:?)
  __virt_addr_valid() (?:?)
  srso_alias_return_thunk() (arch/x86/include/asm/nospec-branch.h:375)
  kasan_addr_to_slab() (mm/kasan/common.c:45)
  kasan_report() (?:?)
  f2fs_get_acl() (fs/f2fs/acl.c:200)
  __get_acl() (fs/posix_acl.c:114)
  vfs_get_acl() (?:?)
  do_get_acl() (?:?)
  __kvmalloc_node_noprof() (?:?)
  do_getxattr() (?:?)
  filename_getxattr() (?:?)
  strncpy_from_user() (?:?)
  path_getxattrat() (fs/xattr.c:838)
  rcu_is_watching() (?:?)
  do_syscall_64() (arch/x86/entry/syscall_64.c:87)
  entry_SYSCALL_64_after_hwframe() (?:?)

Signed-off-by: Zhang Cen <rollkingzzc@gmail.com>

---
diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c
index fa8d81a30fb9..290fee451637 100644
--- a/fs/f2fs/acl.c
+++ b/fs/f2fs/acl.c
@@ -70,7 +70,7 @@ static struct posix_acl *f2fs_acl_from_disk(const char *value, size_t size)
 
 	for (i = 0; i < count; i++) {
 
-		if ((char *)entry > end)
+		if ((char *)entry + sizeof(struct f2fs_acl_entry_short) > end)
 			goto fail;
 
 		acl->a_entries[i].e_tag  = le16_to_cpu(entry->e_tag);
@@ -86,6 +86,8 @@ static struct posix_acl *f2fs_acl_from_disk(const char *value, size_t size)
 			break;
 
 		case ACL_USER:
+			if ((char *)entry + sizeof(struct f2fs_acl_entry) > end)
+				goto fail;
 			acl->a_entries[i].e_uid =
 				make_kuid(&init_user_ns,
 						le32_to_cpu(entry->e_id));
@@ -93,6 +95,8 @@ static struct posix_acl *f2fs_acl_from_disk(const char *value, size_t size)
 					sizeof(struct f2fs_acl_entry));
 			break;
 		case ACL_GROUP:
+			if ((char *)entry + sizeof(struct f2fs_acl_entry) > end)
+				goto fail;
 			acl->a_entries[i].e_gid =
 				make_kgid(&init_user_ns,
 						le32_to_cpu(entry->e_id));

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-05-11  7:08 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-11  7:08 [PATCH] f2fs: validate ACL entry sizes before parsing Zhang Cen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox