diff --git a/SPECS/ntfs-3g/CVE-2026-56135.patch b/SPECS/ntfs-3g/CVE-2026-56135.patch new file mode 100644 index 00000000000..255692be4f8 --- /dev/null +++ b/SPECS/ntfs-3g/CVE-2026-56135.patch @@ -0,0 +1,168 @@ +From 82f48346651391e9d8804368ba21b246a176b516 Mon Sep 17 00:00:00 2001 +From: Azure Linux Security Servicing Account + +Date: Thu, 27 Aug 2026 02:28:21 +0000 +Subject: [PATCH] Patch CVE-2026-56135 for ntfs-3g (applied via patch -p1) + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://github.com/user-attachments/files/29755309/ntfs-3g_2022.10.3-cve_2026-04_8.patch +--- + include/ntfs-3g/acls.h | 2 + + libntfs-3g/acls.c | 85 +++++++++++++++++++++++++++++++++++++++++- + libntfs-3g/security.c | 24 ++++++++++++ + 3 files changed, 110 insertions(+), 1 deletion(-) + +diff --git a/include/ntfs-3g/acls.h b/include/ntfs-3g/acls.h +index 932791e..4f36389 100644 +--- a/include/ntfs-3g/acls.h ++++ b/include/ntfs-3g/acls.h +@@ -168,6 +168,8 @@ char *ntfs_build_descr_posix(struct MAPPING* const mapping[], + + #endif /* POSIXACLS */ + ++int ntfs_inherit_acl_extra_size(const ACL *acl, const SID *usid, ++ const SID *gsid); + int ntfs_inherit_acl(const ACL *oldacl, ACL *newacl, + const SID *usid, const SID *gsid, + BOOL fordir, le16 inherited); +diff --git a/libntfs-3g/acls.c b/libntfs-3g/acls.c +index 4cf534b..0b8c616 100644 +--- a/libntfs-3g/acls.c ++++ b/libntfs-3g/acls.c +@@ -560,7 +560,9 @@ static BOOL valid_acl(const ACL *pacl, unsigned int end) + pace = (const ACCESS_ALLOWED_ACE*) + &((const char*)pacl)[offace]; + acesz = le16_to_cpu(pace->size); +- switch (pace->type) { ++ if (acesz < sizeof(ACE_HEADER)) ++ ok = FALSE; ++ else switch (pace->type) { + case ACCESS_ALLOWED_ACE_TYPE : + case ACCESS_DENIED_ACE_TYPE : + wantsz = ntfs_sid_size(&pace->sid) + 8; +@@ -681,6 +683,87 @@ BOOL ntfs_valid_descr(const char *securattr, unsigned int attrsz) + return (ok); + } + ++/** ++ * ntfs_inherit_acl_extra_size: compute creator SID inheritance slack ++ * @acl: ACL to scan ++ * @usid: owner SID to substitute for CREATOR_OWNER ++ * @gsid: group SID to substitute for CREATOR_GROUP ++ * ++ * Walks @acl bounded by acl->size, adding slack for ALLOW and DENY ACEs ++ * whose SID matches either creator placeholder. ntfs_inherit_acl() can ++ * replace those placeholders by @usid or @gsid and, for directories, can ++ * also keep a verbatim copy for child inheritance. Count the worst-case ++ * extra bytes so the inherited descriptor allocation cannot be overrun. ++ * ++ * Return: extra bytes needed, or 0 if @acl is NULL or structurally rejected. ++ */ ++ ++int ntfs_inherit_acl_extra_size(const ACL *acl, ++ const SID *usid, const SID *gsid) ++{ ++ const ACCESS_ALLOWED_ACE *ace; ++ unsigned int off; ++ unsigned int acl_size; ++ unsigned int acesz; ++ unsigned int sidsz; ++ int usidsz; ++ int gsidsz; ++ int ownersidsz; ++ int groupsidsz; ++ int oldcnt; ++ int nace; ++ int extra; ++ BOOL usid_is_group_sid; ++ ++ extra = 0; ++ if (!acl || !usid || !gsid) ++ return (0); ++ acl_size = le16_to_cpu(acl->size); ++ if (acl_size < sizeof(ACL)) ++ return (0); ++ oldcnt = le16_to_cpu(acl->ace_count); ++ usidsz = ntfs_sid_size(usid); ++ gsidsz = ntfs_sid_size(gsid); ++ ownersidsz = sizeof(ownersidbytes); ++ groupsidsz = sizeof(groupsidbytes); ++ usid_is_group_sid = ntfs_same_sid(usid, groupsid); ++ off = sizeof(ACL); ++ for (nace = 0; nace < oldcnt; nace++) { ++ if (off + 8 > acl_size) ++ break; ++ ace = (const ACCESS_ALLOWED_ACE*)((const char*)acl + off); ++ acesz = le16_to_cpu(ace->size); ++ if (acesz < 8 || acesz > acl_size - off) ++ break; ++ switch (ace->type) { ++ case ACCESS_ALLOWED_ACE_TYPE : ++ case ACCESS_DENIED_ACE_TYPE : ++ if ((acesz >= 8 + sizeof(ownersidbytes)) ++ && ntfs_valid_sid(&ace->sid)) { ++ sidsz = ntfs_sid_size(&ace->sid); ++ if (sidsz <= acesz - 8) { ++ if (ntfs_same_sid(&ace->sid, ownersid)) ++ { ++ extra += usidsz - ownersidsz + ++ 20; ++ if (usid_is_group_sid) ++ extra += gsidsz - ++ groupsidsz + 20; ++ } ++ if (ntfs_same_sid(&ace->sid, groupsid)) ++ extra += gsidsz - groupsidsz + ++ 20; ++ } ++ } ++ break; ++ default : ++ break; ++ } ++ off += acesz; ++ } ++ return extra; ++} ++ + /* + * Copy the inheritable parts of an ACL + * +diff --git a/libntfs-3g/security.c b/libntfs-3g/security.c +index acee0a5..d0e030e 100644 +--- a/libntfs-3g/security.c ++++ b/libntfs-3g/security.c +@@ -3944,6 +3944,30 @@ static le32 build_inherited_id(struct SECURITY_CONTEXT *scx, + usidsz = ntfs_sid_size(usid); + gsidsz = ntfs_sid_size(gsid); + newattrsz = parentattrsz + 3*usidsz + 3*gsidsz; ++ /* ++ * The +3*usidsz + 3*gsidsz slack above only covers a few creator SID ++ * expansions during ntfs_inherit_acl(). Add worst-case slack for every ++ * ALLOW/DENY creator-owner and creator-group ACE in both the parent ++ * DACL and SACL. ++ */ ++ if (pphead->dacl) { ++ offpacl = le32_to_cpu(pphead->dacl); ++ if ((unsigned int)offpacl + sizeof(ACL) <= ++ (unsigned int)parentattrsz) { ++ ppacl = (const ACL*)&parentattr[offpacl]; ++ newattrsz += ntfs_inherit_acl_extra_size(ppacl, ++ usid, gsid); ++ } ++ } ++ if (pphead->sacl) { ++ offpacl = le32_to_cpu(pphead->sacl); ++ if ((unsigned int)offpacl + sizeof(ACL) <= ++ (unsigned int)parentattrsz) { ++ ppacl = (const ACL*)&parentattr[offpacl]; ++ newattrsz += ntfs_inherit_acl_extra_size(ppacl, ++ usid, gsid); ++ } ++ } + if (fordir) + newattrsz *= 2; + newattr = (char*)ntfs_malloc(newattrsz); +-- +2.45.4 + diff --git a/SPECS/ntfs-3g/CVE-2026-56136.patch b/SPECS/ntfs-3g/CVE-2026-56136.patch new file mode 100644 index 00000000000..62a9540fb1a --- /dev/null +++ b/SPECS/ntfs-3g/CVE-2026-56136.patch @@ -0,0 +1,147 @@ +From 42e33edc6318efd7882312ffec38c1f4ba6226a1 Mon Sep 17 00:00:00 2001 +From: Azure Linux Security Servicing Account + +Date: Thu, 27 Aug 2026 02:28:51 +0000 +Subject: [PATCH] Patch CVE-2026-56136 for ntfs-3g (applied via patch -p1) + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://github.com/user-attachments/files/29755343/ntfs-3g_2022.10.3-cve_2026-04_9.patch +--- + include/ntfs-3g/index.h | 1 + + libntfs-3g/attrib.c | 7 ++++++ + libntfs-3g/index.c | 55 ++++++++++++++++++++++++++++++++++++++--- + 3 files changed, 60 insertions(+), 3 deletions(-) + +diff --git a/include/ntfs-3g/index.h b/include/ntfs-3g/index.h +index d001863..1d5845d 100644 +--- a/include/ntfs-3g/index.h ++++ b/include/ntfs-3g/index.h +@@ -143,6 +143,7 @@ extern int ntfs_index_block_inconsistent(const INDEX_BLOCK *ib, u32 block_size, + u64 inum, VCN vcn); + extern int ntfs_index_entry_inconsistent(const INDEX_ENTRY *ie, + COLLATION_RULES collation_rule, u64 inum); ++extern int ntfs_ie_stream_inconsistent(const INDEX_HEADER *ih, u64 inum); + extern int ntfs_index_lookup(const void *key, const int key_len, + ntfs_index_context *ictx) __attribute_warn_unused_result__; + +diff --git a/libntfs-3g/attrib.c b/libntfs-3g/attrib.c +index efb9194..cfc2446 100644 +--- a/libntfs-3g/attrib.c ++++ b/libntfs-3g/attrib.c +@@ -3528,6 +3528,10 @@ int ntfs_attr_inconsistent(const ATTR_RECORD *a, const MFT_REF mref) + if (a->non_resident + || (le32_to_cpu(a->value_length) + < offsetof(INDEX_ROOT, index.reserved)) ++ || (le32_to_cpu(ir->index_block_size) ++ < NTFS_BLOCK_SIZE) ++ || (le32_to_cpu(ir->index_block_size) ++ & (le32_to_cpu(ir->index_block_size) - 1)) + || (le32_to_cpu(ir->index.entries_offset) + < sizeof(INDEX_HEADER)) + || (le32_to_cpu(ir->index.index_length) +@@ -3542,6 +3546,9 @@ int ntfs_attr_inconsistent(const ATTR_RECORD *a, const MFT_REF mref) + (long long)inum); + errno = EIO; + ret = -1; ++ } else if (ntfs_ie_stream_inconsistent(&ir->index, inum)) { ++ errno = EIO; ++ ret = -1; + } + break; + case AT_STANDARD_INFORMATION : +diff --git a/libntfs-3g/index.c b/libntfs-3g/index.c +index e48d6aa..c9651a6 100644 +--- a/libntfs-3g/index.c ++++ b/libntfs-3g/index.c +@@ -504,6 +504,8 @@ int ntfs_index_block_inconsistent(const INDEX_BLOCK *ib, u32 block_size, + (unsigned long long)inum); + return -1; + } ++ if (ntfs_ie_stream_inconsistent(&ib->index, inum)) ++ return -1; + + return (0); + } +@@ -560,7 +562,40 @@ int ntfs_index_entry_inconsistent(const INDEX_ENTRY *ie, + return (ret); + } + +-/** ++int ntfs_ie_stream_inconsistent(const INDEX_HEADER *ih, u64 inum) ++{ ++ const u8 *ies_start = (const u8 *)ih + le32_to_cpu(ih->entries_offset); ++ const u8 *ies_end = (const u8 *)ih + le32_to_cpu(ih->index_length); ++ const u8 *ie; ++ ++ ntfs_log_trace("Entering\n"); ++ ++ for (ie = ies_start; ie < ies_end; ) { ++ u32 len; ++ const INDEX_ENTRY *ent = (const INDEX_ENTRY *)ie; ++ ++ if ((size_t)(ies_end - ie) < sizeof(INDEX_ENTRY_HEADER)) ++ goto err; ++ len = le16_to_cpu(ent->length); ++ if (len < sizeof(INDEX_ENTRY_HEADER) || (len & 7)) ++ goto err; ++ if ((size_t)(ies_end - ie) < len) ++ goto err; ++ if (ent->ie_flags & INDEX_ENTRY_END) { ++ /* END must terminate the stream exactly. */ ++ if (ie + len != ies_end) ++ goto err; ++ return 0; ++ } ++ ie += len; ++ } ++err: ++ ntfs_log_error("Corrupt index entry stream in inode %lld\n", ++ (long long)inum); ++ return -1; ++} ++ ++/** + * Find a key in the index block. + * + * Return values: +@@ -1091,14 +1126,16 @@ out: + + static INDEX_BLOCK *ntfs_ir_to_ib(INDEX_ROOT *ir, VCN ib_vcn) + { ++ u32 ib_size; + INDEX_BLOCK *ib; + INDEX_ENTRY *ie_last; + char *ies_start, *ies_end; + int i; + + ntfs_log_trace("Entering\n"); +- +- ib = ntfs_ib_alloc(ib_vcn, le32_to_cpu(ir->index_block_size), LEAF_NODE); ++ ++ ib_size = le32_to_cpu(ir->index_block_size); ++ ib = ntfs_ib_alloc(ib_vcn, ib_size, LEAF_NODE); + if (!ib) + return NULL; + +@@ -1110,6 +1147,18 @@ static INDEX_BLOCK *ntfs_ir_to_ib(INDEX_ROOT *ir, VCN ib_vcn) + * as well, which can never have any data. + */ + i = (char *)ie_last - ies_start + le16_to_cpu(ie_last->length); ++ ++ if (offsetof(INDEX_BLOCK, index) + le32_to_cpu(ib->index.entries_offset) ++ + i > ib_size) ++ { ++ ntfs_log_error("Last entry in index root overflows the index " ++ "block size: %d (index block size: %lu)\n", ++ i, (unsigned long)ib_size); ++ free(ib); ++ errno = EIO; ++ return NULL; ++ } ++ + memcpy(ntfs_ie_get_first(&ib->index), ies_start, i); + + ib->index.ih_flags = ir->index.ih_flags; +-- +2.45.4 + diff --git a/SPECS/ntfs-3g/ntfs-3g.spec b/SPECS/ntfs-3g/ntfs-3g.spec index 9968b8e4297..511872eaf19 100644 --- a/SPECS/ntfs-3g/ntfs-3g.spec +++ b/SPECS/ntfs-3g/ntfs-3g.spec @@ -1,7 +1,7 @@ Summary: Linux NTFS userspace driver Name: ntfs-3g Version: 2022.10.3 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv2 Vendor: Microsoft Corporation Distribution: Azure Linux @@ -10,6 +10,8 @@ Source0: https://tuxera.com/opensource/%{name}_ntfsprogs-%{version}.tgz Patch0: ntfs-3g_ntfsprogs-2011.10.9-RC-ntfsck-unsupported-return-0.patch Patch1: CVE-2023-52890.patch Patch2: CVE-2026-40706.patch +Patch3: CVE-2026-56135.patch +Patch4: CVE-2026-56136.patch BuildRequires: fuse-devel BuildRequires: gnutls-devel @@ -172,6 +174,9 @@ rm -rf %{buildroot}%{_defaultdocdir}/%{name}/README %exclude %{_mandir}/man8/ntfs-3g* %changelog +* Thu Aug 27 2026 Azure Linux Security Servicing Account - 2022.10.3-4 +- Patch for CVE-2026-56136, CVE-2026-56135 + * Fri Apr 17 2026 Kanishk Bansal - 2022.10.3-3 - Patch CVE-2026-40706