From 082a52e3c7100d452485b6c5ef648cd99fc3395c Mon Sep 17 00:00:00 2001
From: Erik Larsson <erik@tuxera.com>
Date: Tue, 24 Feb 2026 10:04:31 +0200
Subject: [PATCH] acls.c: Fix heap buffer overflow in
 'ntfs_build_permissions_posix'.

The root cause was that the memory allocated for the ACE entries was
insufficient for the worst case scenario when group entries were added
for mask entries that didn't have a corresponding group entry already.
Fixed by allocating space for the worst case number of ACE entries.

This was reported by Andrea Bocchetti with a thorough report which made
it very easy to fix.

This is a backport of the original patch to version 2022.10.3.
---
 libntfs-3g/acls.c | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/libntfs-3g/acls.c b/libntfs-3g/acls.c
index 9f16fecd..4cf534bf 100644
--- a/libntfs-3g/acls.c
+++ b/libntfs-3g/acls.c
@@ -3716,12 +3716,27 @@ struct POSIX_SECURITY *ntfs_build_permissions_posix(
 		/*
 		 * Build a raw posix security descriptor
 		 * by just translating permissions and ids
-		 * Add 2 to the count of ACE to be able to insert
-		 * a group ACE later in access and default ACLs
-		 * and add 2 more to be able to insert ACEs for owner
-		 * and 2 more for other
+		 *
+		 * The worst case number of ACE entries consists of:
+		 * - 'acecount' ACE entries from the main loop (see below)
+		 *   iterating over the 'securattr' array.
+		 * - 1 ACE entry which may be added when creating world
+		 *   permissions if none exist.
+		 * - 1 ACE entry which may be added when setting basic owner
+		 *   permissions if none exist (both lists).
+		 * - 1 ACE entry which may be added when duplicating world
+		 *   permissions as group_obj permissions if none exist.
+		 * - 'acecount + 2' ACE entries which may be added when
+		 *   duplicating world permissions as group permissions if they
+		 *   were converted to masks and the masks are not followed by a
+		 *   group entry.
+		 * - 1 ACE entry which may be added when inserting a default
+		 *   mask if none is present and there are designated users or
+		 *   groups.
+		 *
+		 * This amounts to 2*acecnt + 6 ACE entries in the worst case.
 		 */
-	alloccnt = acecnt + 6;
+	alloccnt = 2*acecnt + 6;
 	pxdesc = (struct POSIX_SECURITY*)malloc(
 				sizeof(struct POSIX_SECURITY)
 				+ alloccnt*sizeof(struct POSIX_ACE));
-- 
2.51.0

