Linux-f2fs-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Zhang Cen <rollkingzzc@gmail.com>
To: Jaegeuk Kim <jaegeuk@kernel.org>, Chao Yu <chao@kernel.org>
Cc: 2045gemini@gmail.com, zerocling0077@gmail.com,
	linux-kernel@vger.kernel.org, Zhang Cen <rollkingzzc@gmail.com>,
	linux-f2fs-devel@lists.sourceforge.net
Subject: [f2fs-dev] [PATCH] f2fs: validate ACL entry sizes before parsing
Date: Mon, 11 May 2026 15:08:43 +0800	[thread overview]
Message-ID: <20260511070843.2112692-1-rollkingzzc@gmail.com> (raw)

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));


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

                 reply	other threads:[~2026-05-11  7:09 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260511070843.2112692-1-rollkingzzc@gmail.com \
    --to=rollkingzzc@gmail.com \
    --cc=2045gemini@gmail.com \
    --cc=chao@kernel.org \
    --cc=jaegeuk@kernel.org \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=zerocling0077@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox