From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f193.google.com (mail-pl1-f193.google.com [209.85.214.193]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2F02F3101B2 for ; Mon, 11 May 2026 07:08:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.193 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778483335; cv=none; b=kJFNCG70SlR1OuEEAPWCicQ4BvxvPXvridJZoztsUU2beYQ2IwiUAjrM29gkWq9Gco+yeu6p/DIM4HLcSxyeFuCVROB4rxig2fKw64IBWUJAGN3uDEMq7fyUUHOEOEhcGkTn4yU/HA1GspDBVKdljHhZE05k8d/Q4PYyYDl7E0c= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778483335; c=relaxed/simple; bh=aoSIndZrhkmDJKclbdVYinJ1eQNDcmPzO7J/epfPgFw=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=KmMXgxpdlDT2gxeRSzqlydwKtH17WxC9TCja8w2SBjxxkUPX4XLPI9mKsYaCZS/HGY/mxTuFQgAhMiaVW6zkEB3SHbW/uiM0nNnOq7bTXylCCBXwUBCEseMeTJ/GT31BBADlPHiV4r71UQk4nvv1VODuap2ARAvgxEFaPOpPk0Y= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=asEn0QKL; arc=none smtp.client-ip=209.85.214.193 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="asEn0QKL" Received: by mail-pl1-f193.google.com with SMTP id d9443c01a7336-2b458ca2296so25558335ad.0 for ; Mon, 11 May 2026 00:08:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778483333; x=1779088133; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=qfUUSCmFNiOS4cO4PS6qgNqN/14FKh66epqOIEkfHQ8=; b=asEn0QKLyR9ZDFoKcmdy3B+ad2srBn2dYLzLdO9yHt9H4TVtWMjmH2W3s0xKQV7YSB tCUWcOze0VqDPyUS1kgjvmmZ75+8fBSL1mnzdP4AcQNJxIoJyN0PxrCJTe+0S/buweco q19HqT/9h6UU/x039YgEeS0Qf6wE/4e3a+f/5hI26jM9E7WzH2xPnm95NhJ8at3Eu044 ZL1Q/UlalfEgkO67bRMc8hm2NeyzdyCPB54IyeyFsxYuZIqnfKRcUonP3DCq7EJH8/TH z6jqyljn2A+L8fEaA5BO81fDCV3x5ONCiFvvk5MFSJ+/nM/dAXOusCfjaUEMm1oG+qfm PQ6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778483334; x=1779088134; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=qfUUSCmFNiOS4cO4PS6qgNqN/14FKh66epqOIEkfHQ8=; b=Acv/vI5JNwmXBq62EvNqCd1/PqYn6P99N4/d9Kxo9dlMgQ1OgUMts5ujr9Z2D52VKb /OxjdNr+pXWwWygvkpfobjd5f8YOvDJ+JtxDvPFcIyYu4zIwavTVpdL6lHnwzDk5Tanx FFMzlmje0Vkp32oDhJZ4LRrlQVkEEPMf0NRW8AzAwhjmxJxyku3rbEY4gWOiK1IuieGQ 7xMzgpYwSc69V8MA6VavqUcsqwWbCDnm7ODkcMaSzno/5cVgygPbOfuPpGgKMtr0gzVh VXHU40IgbFDNRM7AWXZhfTC6OjGX7C1KreUA7330RJG63RWsfXhdHIDM1hOiiua8JqHn qlIA== X-Forwarded-Encrypted: i=1; AFNElJ8ZbzDRVQYXt7YSs1qYaeznBS0NbyGqz8BMejS++rjszgseUhEFmOEUwH2mcW4XafPiafx6cy//qh0fUrk=@vger.kernel.org X-Gm-Message-State: AOJu0YynoFvKFVYO6cKd8wp1PIIfOmzSNEeYNaQlf8eAFVUz9rSfK7eT ZzxTRPauwPDbmwNcrbnUZ4hLAKAY2RfdHCOH/WSltaUH3FpESjQ7cTE7 X-Gm-Gg: Acq92OEdAkmkc4pqW5aptVY+/rzS5gNvkMb+KHaW3SPylxl4J6GTzgAQ7j6KCBHm88S CZe2FSDaDqoU88FKT4XQFkhINVTs8L3r+DIt6PJJOB0ycbLKTKQks2Y7YF2oHE6qapfF5g4OnXM QR5JIWfdr1QrADKiTs/gr+Sl4LGInbpBwrgw2P/iPh/DDnQUv4UPhn9klRWmt61fPAA7bOMXKne 67fOXuIjujt07t1br1OUP4lVoXCe4TieJ23SUF2bEruHfr6ceVBYvgaAPNe/2/lhFTKd/UklUSg /wINHk0HSFDwMEqHacdua+BBk16bESE+aNu5MMZbZCMF0WrlE0rR9A0jX1y7OxNK4kUUlXlZ3SX bILTkXvPTNajxYDrlLJxAlF2W7gkVgWGi4Rs2gmPo03Asx9Qipwz33PY3YocVcaXuHa0RCcQw9r klrAjBAs7WGJ32SVrE96G/kZ6mf4V7p95NAQoOi4StOA== X-Received: by 2002:a17:902:f30e:b0:2b0:b41e:c5c3 with SMTP id d9443c01a7336-2baf0e04babmr99821945ad.29.1778483333377; Mon, 11 May 2026 00:08:53 -0700 (PDT) Received: from localhost ([111.228.63.84]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2baf1e78c6csm95818865ad.60.2026.05.11.00.08.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 11 May 2026 00:08:52 -0700 (PDT) From: Zhang Cen To: Jaegeuk Kim , Chao Yu Cc: linux-f2fs-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org, zerocling0077@gmail.com, 2045gemini@gmail.com, Zhang Cen Subject: [PATCH] f2fs: validate ACL entry sizes before parsing Date: Mon, 11 May 2026 15:08:43 +0800 Message-Id: <20260511070843.2112692-1-rollkingzzc@gmail.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 --- 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));