public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Tom spot Callaway <spotaws@amazon.com>
To: git-commits@fedoraproject.org
Subject: [rpms/ntfs-3g] epel9: apply upstream patches to resolve NTFS-3G-SA_2026-06-1_20 NTFS-3G-SA_2026-06-1_19 NTFS-3G-SA_2026-06-1_12 NTFS-3G-SA_2026-06-1_11 NTFS-3G-SA_2026-06-1_10 NTFS-3G-SA_2026-06-1_08 NTFS-3G-SA_2026-06-1_07 NTFS-3G-SA_2026-06-1_05
Date: Fri, 25 Sep 2026 13:55:02 GMT	[thread overview]
Message-ID: <179034450276.1.4746638571089181808.rpms-ntfs-3g-02e2180d538f@fedoraproject.org> (raw)

A new commit has been pushed.

Repo   : rpms/ntfs-3g
Branch : epel9
Commit : 02e2180d538f5916cdddb2d4b9a8618b481c97aa
Author : Tom spot Callaway <spotaws@amazon.com>
Date   : 2026-09-25T09:54:57-04:00
Stats  : +503/-1 in 9 file(s)
URL    : https://src.fedoraproject.org/rpms/ntfs-3g/c/02e2180d538f5916cdddb2d4b9a8618b481c97aa?branch=epel9

Log:
apply upstream patches to resolve NTFS-3G-SA_2026-06-1_20 NTFS-3G-SA_2026-06-1_19 NTFS-3G-SA_2026-06-1_12 NTFS-3G-SA_2026-06-1_11 NTFS-3G-SA_2026-06-1_10 NTFS-3G-SA_2026-06-1_08 NTFS-3G-SA_2026-06-1_07 NTFS-3G-SA_2026-06-1_05

---
diff --git a/1_ntfs-3g_2022.10.3-SA_2026-06-1_05.patch b/1_ntfs-3g_2022.10.3-SA_2026-06-1_05.patch
new file mode 100644
index 0000000..ac4fb49
--- /dev/null
+++ b/1_ntfs-3g_2022.10.3-SA_2026-06-1_05.patch
@@ -0,0 +1,27 @@
+diff --git a/libntfs-3g/index.c b/libntfs-3g/index.c
+index e48d6aafb..c2cdf23a7 100644
+--- a/libntfs-3g/index.c
++++ b/libntfs-3g/index.c
+@@ -1379,12 +1379,19 @@ static int ntfs_ir_make_space(ntfs_index_context *icx, int data_size)
+ static int ntfs_ie_add_vcn(INDEX_ENTRY **ie)
+ {
+ 	INDEX_ENTRY *p, *old = *ie;
+-	 
+-	old->length = cpu_to_le16(le16_to_cpu(old->length) + sizeof(VCN));
+-	p = realloc(old, le16_to_cpu(old->length));
++	u32 new_length = le16_to_cpu(old->length) + (u32)sizeof(VCN);
++
++	if (new_length > 0xffff) {
++		ntfs_log_error("Index entry of length %u cannot hold a VCN\n",
++				(unsigned)le16_to_cpu(old->length));
++		errno = EIO;
++		return STATUS_ERROR;
++	}
++	p = realloc(old, new_length);
+ 	if (!p)
+ 		return STATUS_ERROR;
+ 	
++	p->length = cpu_to_le16(new_length);
+ 	p->ie_flags |= INDEX_ENTRY_NODE;
+ 	*ie = p;
+ 

diff --git a/2_ntfs-3g_2022.10.3-SA_2026-06-1_07.patch b/2_ntfs-3g_2022.10.3-SA_2026-06-1_07.patch
new file mode 100644
index 0000000..e3a35ab
--- /dev/null
+++ b/2_ntfs-3g_2022.10.3-SA_2026-06-1_07.patch
@@ -0,0 +1,46 @@
+diff --git a/libntfs-3g/attrib.c b/libntfs-3g/attrib.c
+index efb919438..fdd8b17ee 100644
+--- a/libntfs-3g/attrib.c
++++ b/libntfs-3g/attrib.c
+@@ -2671,8 +2671,17 @@ s64 ntfs_attr_mst_pread(ntfs_attr *na, const s64 pos, const s64 bk_cnt,
+ 		/* log errors unless silenced */
+ 	warn = !na->ni || !na->ni->vol || !NVolNoFixupWarn(na->ni->vol);
+ 	for (end = (u8*)dst + br * bk_size; (u8*)dst < end; dst = (u8*)dst +
+-			bk_size)
+-		ntfs_mst_post_read_fixup_warn((NTFS_RECORD*)dst, bk_size, warn);
++			bk_size) {
++		/*
++		 * A record which cannot be multi sector transfer protected at
++		 * all (EINVAL) has not been deprotected, so it must not be
++		 * used. A record damaged by an incomplete transfer (EIO) is
++		 * left to the caller, which detects it by the BAAD magic.
++		 */
++		if (ntfs_mst_post_read_fixup_warn((NTFS_RECORD*)dst, bk_size,
++					warn) && (errno == EINVAL))
++			return -1;
++	}
+ 	/* Finally, return the number of blocks read. */
+ 	return br;
+ }
+diff --git a/libntfs-3g/runlist.c b/libntfs-3g/runlist.c
+index cb01e5a77..9793f88d7 100644
+--- a/libntfs-3g/runlist.c
++++ b/libntfs-3g/runlist.c
+@@ -790,7 +790,7 @@ static runlist_element *ntfs_mapping_pairs_decompress_i(const ntfs_volume *vol,
+ 	const u8 *buf;		/* Current position in mapping pairs array. */
+ 	const u8 *attr_end;	/* End of attribute. */
+ 	int err, rlsize;	/* Size of runlist buffer. */
+-	u16 rlpos;		/* Current runlist position in units of
++	int rlpos;		/* Current runlist position in units of
+ 				   runlist_elements. */
+ 	u8 b;			/* Current byte offset in buf. */
+ 
+@@ -832,7 +832,7 @@ static runlist_element *ntfs_mapping_pairs_decompress_i(const ntfs_volume *vol,
+ 		 * Allocate more memory if needed, including space for the
+ 		 * not-mapped and terminator elements.
+ 		 */
+-		if ((int)((rlpos + 3) * sizeof(*old_rl)) > rlsize) {
++		if ((rlpos + 3) > (rlsize / (int)sizeof(*old_rl))) {
+ 			runlist_element *rl2;
+ 
+ 			rlsize += 0x1000;

diff --git a/3_ntfs-3g_2022.10.3-SA_2026-06-1_08.patch b/3_ntfs-3g_2022.10.3-SA_2026-06-1_08.patch
new file mode 100644
index 0000000..391b041
--- /dev/null
+++ b/3_ntfs-3g_2022.10.3-SA_2026-06-1_08.patch
@@ -0,0 +1,25 @@
+diff --git a/libntfs-3g/attrib.c b/libntfs-3g/attrib.c
+index efb919438..4570f6820 100644
+--- a/libntfs-3g/attrib.c
++++ b/libntfs-3g/attrib.c
+@@ -3338,6 +3338,20 @@ do_next_attr_loop:
+ 		 */
+ 		if (al_entry->type != a->type)
+ 			break;
++		/*
++		 * The same check is made in ntfs_attr_inconsistent() when the
++		 * mft record is read, but that validation is skipped for the
++		 * tools which set NVolNoFixupWarn(), so the name has to be
++		 * checked here as well.
++		 */
++		if (a->name_length && ((le16_to_cpu(a->name_offset)
++				+ a->name_length * sizeof(ntfschar))
++				> le32_to_cpu(a->length))) {
++			ntfs_log_error("Corrupt attribute name"
++				" in MFT record %lld\n",
++				(long long)ctx->ntfs_ino->mft_no);
++			break;
++		}
+ 		if (!ntfs_names_are_equal((ntfschar*)((char*)a +
+ 				le16_to_cpu(a->name_offset)),
+ 				a->name_length, al_name,

diff --git a/4_ntfs-3g_2022.10.3-SA_2026-06-1_10.patch b/4_ntfs-3g_2022.10.3-SA_2026-06-1_10.patch
new file mode 100644
index 0000000..b0a0316
--- /dev/null
+++ b/4_ntfs-3g_2022.10.3-SA_2026-06-1_10.patch
@@ -0,0 +1,113 @@
+diff --git a/libntfs-3g/ea.c b/libntfs-3g/ea.c
+index b86930abd..05daa53d1 100644
+--- a/libntfs-3g/ea.c
++++ b/libntfs-3g/ea.c
+@@ -183,6 +183,60 @@ static int ntfs_update_ea(ntfs_inode *ni, const char *value, size_t size,
+ 	return (res);
+ }
+ 
++/**
++ * ntfs_ea_inconsistent - check that one EA record is sane
++ * @p_ea:	the EA record to check
++ * @offs:	where the record starts in the EA buffer
++ * @size:	size of the EA buffer
++ *
++ * Every EA record says where the next one starts. Check that the record fits
++ * in the buffer and that its name and value fit in the record :
++ *
++ *      offs                                                  nextoffs
++ *       |                                                        |
++ *       | header |      name      | NUL |     value      |  pad  |
++ *       |========|================|=====|================|=======|
++ *       |        |                |     |                |       |
++ *       |<- 8 -->|<- name_length->|<-1->|<-value_length->|<-0..3>|
++ *       |<---------------- next_entry_offset ------------------->|
++ *
++ * nextoffs is @offs + next_entry_offset. It has to move forward & be a
++ * multiple of 4 and stay inside the buffer. The name must not be empty and
++ * must be null terminated. Also the name and value must end at nextoffs or
++ * at most 3 bytes before it. The rest of it being padding.
++ *
++ * These are the checks which used to be inlined in ntfs_set_ntfs_ea(). The
++ * caller must have checked that @offs is inside the buffer and that the 8
++ * byte header fits.
++ *
++ * Return 0 if the record is sane and -1 if it is not.
++ */
++
++static int ntfs_ea_inconsistent(const EA_ATTR *p_ea, size_t offs, size_t size)
++{
++	size_t nextoffs;
++	BOOL ok;
++
++	nextoffs = offs + le32_to_cpu(p_ea->next_entry_offset);
++		/* null offset to next not allowed */
++	ok = (nextoffs > offs)
++			&& (nextoffs <= size)
++			&& !(nextoffs & 3)
++			&& p_ea->name_length
++				/* zero sized value are allowed */
++			&& ((offs + offsetof(EA_ATTR,name)
++				+ p_ea->name_length + 1
++				+ le16_to_cpu(p_ea->value_length))
++					<= nextoffs)
++			&& ((offs + offsetof(EA_ATTR,name)
++				+ p_ea->name_length + 1
++				+ le16_to_cpu(p_ea->value_length))
++					>= (nextoffs - 3))
++			&& !p_ea->name[p_ea->name_length];
++	/* name not checked, as chkdsk accepts any chars */
++	return ok ? 0 : -1;
++}
++
+ /*
+  *		Return the existing EA
+  *
+@@ -263,22 +317,7 @@ int ntfs_set_ntfs_ea(ntfs_inode *ni, const char *value, size_t size, int flags)
+ 		while (ok && (offs < size)) {
+ 			p_ea = (const EA_ATTR*)&value[offs];
+ 			nextoffs = offs + le32_to_cpu(p_ea->next_entry_offset);
+-				/* null offset to next not allowed */
+-			ok = (nextoffs > offs)
+-			    && (nextoffs <= size)
+-			    && !(nextoffs & 3)
+-			    && p_ea->name_length
+-				/* zero sized value are allowed */
+-			    && ((offs + offsetof(EA_ATTR,name)
+-				+ p_ea->name_length + 1
+-				+ le16_to_cpu(p_ea->value_length))
+-				    <= nextoffs)
+-			    && ((offs + offsetof(EA_ATTR,name)
+-				+ p_ea->name_length + 1
+-				+ le16_to_cpu(p_ea->value_length))
+-				    >= (nextoffs - 3))
+-			    && !p_ea->name[p_ea->name_length];
+-			/* name not checked, as chkdsk accepts any chars */
++			ok = !ntfs_ea_inconsistent(p_ea, offs, size);
+ 			if (ok) {
+ 				if (p_ea->flags & NEED_EA)
+ 					ea_count++;
+@@ -444,16 +483,20 @@ int ntfs_ea_check_wsldev(ntfs_inode *ni, dev_t *rdevp)
+ 		offset = 0;
+ 		found = FALSE;
+ 		do {
++			/* The fixed header must fit in the remaining buffer. */
++			if ((lth - offset) < (int)offsetof(EA_ATTR, name))
++				break;
+ 			p_ea = (const EA_ATTR*)&buf[offset];
++			if (ntfs_ea_inconsistent(p_ea, offset, lth))
++				break;
+ 			next = le32_to_cpu(p_ea->next_entry_offset);
+-			found = ((next > (int)(sizeof(lxdev) + sizeof(device)))
+-				&& (p_ea->name_length == (sizeof(lxdev) - 1))
++			found = ((p_ea->name_length == (sizeof(lxdev) - 1))
+ 				&& (p_ea->value_length
+ 					== const_cpu_to_le16(sizeof(device)))
+ 				&& !memcmp(p_ea->name, lxdev, sizeof(lxdev)));
+ 			if (!found)
+ 				offset += next;
+-		} while (!found && (next > 0) && (offset < lth));
++		} while (!found && (offset < lth));
+ 		if (found) {
+ 				/* beware of alignment */
+ 			memcpy(&device, &p_ea->name[p_ea->name_length + 1],

diff --git a/5_ntfs-3g_2022.10.3-SA_2026-06-1_11.patch b/5_ntfs-3g_2022.10.3-SA_2026-06-1_11.patch
new file mode 100644
index 0000000..35fc73b
--- /dev/null
+++ b/5_ntfs-3g_2022.10.3-SA_2026-06-1_11.patch
@@ -0,0 +1,28 @@
+diff --git a/libntfs-3g/logfile.c b/libntfs-3g/logfile.c
+index 9c3155e78..e5e8af63c 100644
+--- a/libntfs-3g/logfile.c
++++ b/libntfs-3g/logfile.c
+@@ -177,14 +177,16 @@ static BOOL ntfs_check_restart_area(RESTART_PAGE_HEADER *rp)
+ 	ra_ofs = le16_to_cpu(rp->restart_area_offset);
+ 	ra = (RESTART_AREA*)((u8*)rp + ra_ofs);
+ 	/*
+-	 * Everything before ra->file_size must be before the first word
+-	 * protected by an update sequence number.  This ensures that it is
+-	 * safe to access ra->client_array_offset.
++	 * The fixed RESTART_AREA prefix must be entirely before the first
++	 * MST-protected sector word.  Fixups have not been applied yet, so this
++	 * makes every fixed field accessed below safe to read.
++	 *
++	 * The subsequent client_array_offset check bounds any format-specific
++	 * extension before the client array.
+ 	 */
+-	if (ra_ofs + offsetof(RESTART_AREA, file_size) >
+-			NTFS_BLOCK_SIZE - sizeof(u16)) {
+-		ntfs_log_error("$LogFile restart area specifies "
+-				"inconsistent file offset.\n");
++	if (ra_ofs + sizeof(RESTART_AREA) > NTFS_BLOCK_SIZE - sizeof(u16)) {
++		ntfs_log_error("$LogFile restart area extends into the first "
++				"MST-protected sector word.\n");
+ 		return FALSE;
+ 	}
+ 	/*

diff --git a/6_ntfs-3g_2022.10.3-SA_2026-06-1_12.patch b/6_ntfs-3g_2022.10.3-SA_2026-06-1_12.patch
new file mode 100644
index 0000000..3bff194
--- /dev/null
+++ b/6_ntfs-3g_2022.10.3-SA_2026-06-1_12.patch
@@ -0,0 +1,73 @@
+diff --git a/include/ntfs-3g/attrlist.h b/include/ntfs-3g/attrlist.h
+index 2952e48b8..44027933f 100644
+--- a/include/ntfs-3g/attrlist.h
++++ b/include/ntfs-3g/attrlist.h
+@@ -26,6 +26,9 @@
+ 
+ #include "attrib.h"
+ 
++extern int ntfs_attrlist_entry_inconsistent(const ntfs_inode *ni,
++				const ATTR_LIST_ENTRY *ale);
++
+ extern int ntfs_attrlist_need(ntfs_inode *ni);
+ 
+ extern int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr);
+diff --git a/libntfs-3g/attrlist.c b/libntfs-3g/attrlist.c
+index 29d408598..c06c0edb2 100644
+--- a/libntfs-3g/attrlist.c
++++ b/libntfs-3g/attrlist.c
+@@ -45,6 +45,32 @@
+ #include "logging.h"
+ #include "misc.h"
+ 
++/**
++ * ntfs_attrlist_entry_inconsistent - check an attribute list entry
++ * @ni:		inode whose attribute list is being walked
++ * @ale:	entry to check
++ *
++ * The entry has to lie fully within the attribute list so that its fields can
++ * be read, and it has to be long enough for a walk to make progress.
++ *
++ * Return 0 if the entry may be used and -1 if it may not, with errno set to
++ * EIO.
++ */
++int ntfs_attrlist_entry_inconsistent(const ntfs_inode *ni,
++				const ATTR_LIST_ENTRY *ale)
++{
++	u32 length = le16_to_cpu(ale->length);
++
++	if ((length < sizeof(ATTR_LIST_ENTRY)) || (((const u8*)ale + length)
++			> (ni->attr_list + ni->attr_list_size))) {
++		ntfs_log_error("Corrupt attribute list entry in inode %lld\n",
++				(long long)ni->mft_no);
++		errno = EIO;
++		return -1;
++	}
++	return 0;
++}
++
+ /**
+  * ntfs_attrlist_need - check whether inode need attribute list
+  * @ni:		opened ntfs inode for which perform check
+@@ -85,6 +111,8 @@ int ntfs_attrlist_need(ntfs_inode *ni)
+ 	errno = 0;
+ 	ale = (ATTR_LIST_ENTRY *)ni->attr_list;
+ 	while ((u8*)ale < ni->attr_list + ni->attr_list_size) {
++		if (ntfs_attrlist_entry_inconsistent(ni, ale))
++			return -1;
+ 		if (MREF_LE(ale->mft_reference) != ni->mft_no)
+ 			return 1;
+ 		ale = (ATTR_LIST_ENTRY *)((u8*)ale + le16_to_cpu(ale->length));
+diff --git a/libntfs-3g/inode.c b/libntfs-3g/inode.c
+index 8819ff1dc..605b60dff 100644
+--- a/libntfs-3g/inode.c
++++ b/libntfs-3g/inode.c
+@@ -716,6 +716,8 @@ int ntfs_inode_attach_all_extents(ntfs_inode *ni)
+ 	errno = 0;
+ 	ale = (ATTR_LIST_ENTRY *)ni->attr_list;
+ 	while ((u8*)ale < ni->attr_list + ni->attr_list_size) {
++		if (ntfs_attrlist_entry_inconsistent(ni, ale))
++			return -1;
+ 		if (ni->mft_no != MREF_LE(ale->mft_reference) &&
+ 				prev_attached != MREF_LE(ale->mft_reference)) {
+ 			if (!ntfs_extent_inode_open(ni, ale->mft_reference)) {

diff --git a/7_ntfs-3g_2022.10.3-SA_2026-06-1_19.patch b/7_ntfs-3g_2022.10.3-SA_2026-06-1_19.patch
new file mode 100644
index 0000000..3a0092c
--- /dev/null
+++ b/7_ntfs-3g_2022.10.3-SA_2026-06-1_19.patch
@@ -0,0 +1,142 @@
+diff --git a/libntfs-3g/acls.c b/libntfs-3g/acls.c
+index 9f16fecd0..d7c5ef8cd 100644
+--- a/libntfs-3g/acls.c
++++ b/libntfs-3g/acls.c
+@@ -595,6 +595,59 @@ static BOOL valid_acl(const ACL *pacl, unsigned int end)
+ 	return (ok);
+ }
+ 
++/**
++ * sid_at_standard_offset - check whether an ACE keeps its SID where expected
++ * @pace:	the ACE to check
++ *
++ * Most ACE types keep the SID just after the header and the access mask :
++ *
++ *      | header | mask |              SID              |
++ *      |========|======|===============================|
++ *      0        4      8
++ *
++ * The object types first keep a flag word and up to two GUIDs. The flags tell
++ * which of the GUIDs are present so the SID may begin at 12 or 28 or 44 :
++ *
++ *      | header | mask | flags | object type | inherited object type | SID |
++ *      |========|======|=======|=============|=======================|=====|
++ *      0        4      8      12            28                      44
++ *
++ * So for an object type the SID cannot even be located from the type alone.
++ *
++ * The types listed below are the ones whose SID valid_acl() has checked, so
++ * for them the SID is known to lie within the ACE. The others either move the
++ * SID as shown above or are reserved with no defined layout, and for those the
++ * bytes at the standard offset are not a SID and must not be read as one.
++ *
++ * The list is the set of types in MS-DTYP section 2.4.4.1 which are neither an
++ * object type nor reserved. It has to be kept in step with valid_acl().
++ *
++ * Return TRUE if the SID is at the standard offset and FALSE otherwise.
++ */
++
++static BOOL sid_at_standard_offset(const ACCESS_ALLOWED_ACE *pace)
++{
++	BOOL standard;
++
++	switch (pace->type) {
++	case ACCESS_ALLOWED_ACE_TYPE :
++	case ACCESS_DENIED_ACE_TYPE :
++	case SYSTEM_AUDIT_ACE_TYPE :
++	case ACCESS_ALLOWED_CALLBACK_ACE_TYPE :
++	case ACCESS_DENIED_CALLBACK_ACE_TYPE :
++	case SYSTEM_AUDIT_CALLBACK_ACE_TYPE :
++	case SYSTEM_MANDATORY_LABEL_ACE_TYPE :
++	case SYSTEM_RESOURCE_ATTRIBUTE_ACE_TYPE :
++	case SYSTEM_SCOPED_POLICY_ID_ACE_TYPE :
++		standard = TRUE;
++		break;
++	default :
++		standard = FALSE;
++		break;
++	}
++	return (standard);
++}
++
+ /*
+  *		Do sanity checks on security descriptors read from storage
+  *	basically, we make sure that every field holds within
+@@ -656,6 +709,30 @@ BOOL ntfs_valid_descr(const char *securattr, unsigned int attrsz)
+ 		&& (ntfs_attr_size(securattr) <= attrsz)
+ 		&& ntfs_valid_sid((const SID*)&securattr[offowner])
+ 		&& ntfs_valid_sid((const SID*)&securattr[offgroup])
++			/*
++			 * Check that the owner and group SIDs, and the ACLs,
++			 * end within the allocated storage.
++			 *
++			 * ntfs_attr_size() cannot be relied on for this. It
++			 * only takes a field into account when the field lies
++			 * beyond the ones examined before it, so a field at a
++			 * lower offset is left out of the size it returns. The
++			 * owner SID is the usual case, as it is placed before
++			 * the group SID in most descriptors.
++			 *
++			 * The SID sizes are known sane here because
++			 * ntfs_valid_sid() has just bounded the sub authority
++			 * count, and the ACL sizes are readable because the
++			 * ACL headers were checked to be within storage.
++			 */
++		&& ((offowner + (unsigned int)ntfs_sid_size((const SID*)
++				&securattr[offowner])) <= attrsz)
++		&& ((offgroup + (unsigned int)ntfs_sid_size((const SID*)
++				&securattr[offgroup])) <= attrsz)
++		&& (!offdacl
++				|| ((offdacl + le16_to_cpu(pdacl->size)) <= attrsz))
++		&& (!offsacl
++				|| ((offsacl + le16_to_cpu(psacl->size)) <= attrsz))
+ 			/*
+ 			 * if there is an ACL, as indicated by offdacl,
+ 			 * require SE_DACL_PRESENT
+@@ -3220,7 +3297,8 @@ static int build_std_permissions(const char *securattr,
+ 	}
+ 	for (nace = 0; nace < acecnt; nace++) {
+ 		pace = (const ACCESS_ALLOWED_ACE*)&securattr[offace];
+-		if (!(pace->flags & INHERIT_ONLY_ACE)) {
++		if (!(pace->flags & INHERIT_ONLY_ACE)
++		   && sid_at_standard_offset(pace)) {
+ 			if (ntfs_same_sid(usid, &pace->sid)
+ 			  || ntfs_same_sid(ownersid, &pace->sid)) {
+ 				noown = FALSE;
+@@ -3310,7 +3388,8 @@ static int build_owngrp_permissions(const char *securattr,
+ 	}
+ 	for (nace = 0; nace < acecnt; nace++) {
+ 		pace = (const ACCESS_ALLOWED_ACE*)&securattr[offace];
+-		if (!(pace->flags & INHERIT_ONLY_ACE)) {
++		if (!(pace->flags & INHERIT_ONLY_ACE)
++		   && sid_at_standard_offset(pace)) {
+ 			if ((ntfs_same_sid(usid, &pace->sid)
+ 			   || ntfs_same_sid(ownersid, &pace->sid))
+ 			    && (pace->mask & WRITE_OWNER)) {
+@@ -3501,7 +3580,8 @@ static int build_ownadmin_permissions(const char *securattr,
+ 	for (nace = 0; nace < acecnt; nace++) {
+ 		pace = (const ACCESS_ALLOWED_ACE*)&securattr[offace];
+ 		if (!(pace->flags & INHERIT_ONLY_ACE)
+-		   && !(~pace->mask & (ROOT_OWNER_UNMARK | ROOT_GROUP_UNMARK))) {
++		   && !(~pace->mask & (ROOT_OWNER_UNMARK | ROOT_GROUP_UNMARK))
++		   && sid_at_standard_offset(pace)) {
+ 			if ((ntfs_same_sid(usid, &pace->sid)
+ 			   || ntfs_same_sid(ownersid, &pace->sid))
+ 			     && (((pace->mask & WRITE_OWNER) && firstapply))) {
+@@ -3748,6 +3828,16 @@ struct POSIX_SECURITY *ntfs_build_permissions_posix(
+ 			pctx = &ctx[0];
+ 		}
+ 		ignore = FALSE;
++			/*
++			 * Only look for a SID at the standard offset when the
++			 * ACE type keeps one there. An ACE which does not
++			 * could never contribute to the Posix ACL below, as
++			 * that needs an allow or deny type.
++			 */
++		if (!sid_at_standard_offset(pace)) {
++			offace += le16_to_cpu(pace->size);
++			continue;
++		}
+ 			/*
+ 			 * grants for root as a designated user or group
+ 			 */

diff --git a/8_ntfs-3g_2022.10.3-SA_2026-06-1_20.patch b/8_ntfs-3g_2022.10.3-SA_2026-06-1_20.patch
new file mode 100644
index 0000000..dbef138
--- /dev/null
+++ b/8_ntfs-3g_2022.10.3-SA_2026-06-1_20.patch
@@ -0,0 +1,29 @@
+diff --git a/libntfs-3g/acls.c b/libntfs-3g/acls.c
+index 9f16fecd0..ff5f723db 100644
+--- a/libntfs-3g/acls.c
++++ b/libntfs-3g/acls.c
+@@ -3581,14 +3581,22 @@ const SID *ntfs_acl_owner(const char *securattr)
+ 		acecnt = le16_to_cpu(pacl->ace_count);
+ 		offace = offdacl + sizeof(ACL);
+ 		nace = 0;
+-		do {
++			/*
++			 * Test the count before reading an ACE. An empty ACL
++			 * has none to read and the bytes which would hold the
++			 * first one are not part of the ACL. valid_acl() has
++			 * not checked them either because it had no ACE to
++			 * walk.
++			 */
++		while (!found && (nace < acecnt)) {
+ 			pace = (const ACCESS_ALLOWED_ACE*)&securattr[offace];
+ 			if ((pace->mask & WRITE_OWNER)
+ 			   && (pace->type == ACCESS_ALLOWED_ACE_TYPE)
+ 			   && ntfs_is_user_sid(&pace->sid))
+ 				found = TRUE;
+ 			offace += le16_to_cpu(pace->size);
+-		} while (!found && (++nace < acecnt));
++			nace++;
++		}
+ 	}
+ 	if (found)
+ 		usid = &pace->sid;

diff --git a/ntfs-3g.spec b/ntfs-3g.spec
index 7d6df1a..f48783d 100644
--- a/ntfs-3g.spec
+++ b/ntfs-3g.spec
@@ -8,7 +8,7 @@
 Name:           ntfs-3g
 Epoch:          2
 Version:        2022.10.3
-Release:        11%{?dist}
+Release:        12%{?dist}
 Summary:        Linux NTFS userspace driver
 # Automatically converted from old format: GPLv2+ - review is highly recommended.
 License:        GPL-2.0-or-later
@@ -38,6 +38,14 @@ Patch105:       6_ntfs-3g_2022.10.3-CVE-2026-46570.patch
 # Patch106:       7_ntfs-3g_2022.10.3-CVE-2026-46572.patch
 Patch107:       8_ntfs-3g_2022.10.3-CVE-2026-56135.patch
 # Patch108:       9_ntfs-3g_2022.10.3-CVE-2026-56136.patch
+Patch109:       1_ntfs-3g_2022.10.3-SA_2026-06-1_05.patch
+Patch110:       2_ntfs-3g_2022.10.3-SA_2026-06-1_07.patch
+Patch111:       3_ntfs-3g_2022.10.3-SA_2026-06-1_08.patch
+Patch112:       4_ntfs-3g_2022.10.3-SA_2026-06-1_10.patch
+Patch113:       5_ntfs-3g_2022.10.3-SA_2026-06-1_11.patch
+Patch114:       6_ntfs-3g_2022.10.3-SA_2026-06-1_12.patch
+Patch115:       7_ntfs-3g_2022.10.3-SA_2026-06-1_19.patch
+Patch116:       8_ntfs-3g_2022.10.3-SA_2026-06-1_20.patch
 
 BuildRequires:  make
 # ntfs-3g BuildRequires
@@ -216,6 +224,17 @@ rm -rf %{buildroot}%{_defaultdocdir}/%{name}/README
 %exclude %{_mandir}/man8/ntfs-3g*
 
 %changelog
+* Fri Sep 25 2026 Tom Callaway <spot@fedoraproject.org> - 2:2022.10.3-12
+- apply upstream patches for:
+  NTFS-3G-SA_2026-06-1_20
+  NTFS-3G-SA_2026-06-1_19
+  NTFS-3G-SA_2026-06-1_12
+  NTFS-3G-SA_2026-06-1_11
+  NTFS-3G-SA_2026-06-1_10
+  NTFS-3G-SA_2026-06-1_08
+  NTFS-3G-SA_2026-06-1_07
+  NTFS-3G-SA_2026-06-1_05
+
 * Thu Sep 24 2026 Tom Callaway <spot@fedoraproject.org> - 2:2022.10.3-11
 - apply upstream patches for:
   CVE-2026-42616 CVE-2026-42617 CVE-2026-42618

                 reply	other threads:[~2026-09-25 13:55 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=179034450276.1.4746638571089181808.rpms-ntfs-3g-02e2180d538f@fedoraproject.org \
    --to=spotaws@amazon.com \
    --cc=git-commits@fedoraproject.org \
    /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