From: Greg Kroah-Hartman Date: Thu, 14 May 2026 13:19:47 +0000 (+0200) Subject: 6.1-stable patches X-Git-Tag: v6.12.88~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e5e140ba1e07b975444285cda13f324235e32354;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: ksmbd-validate-inherited-ace-sid-length.patch --- diff --git a/queue-6.1/ksmbd-validate-inherited-ace-sid-length.patch b/queue-6.1/ksmbd-validate-inherited-ace-sid-length.patch new file mode 100644 index 0000000000..552e083c79 --- /dev/null +++ b/queue-6.1/ksmbd-validate-inherited-ace-sid-length.patch @@ -0,0 +1,145 @@ +From 996454bc0da84d5a1dedb1a7861823087e01a7ae Mon Sep 17 00:00:00 2001 +From: Shota Zaizen +Date: Tue, 28 Apr 2026 19:02:55 +0900 +Subject: ksmbd: validate inherited ACE SID length + +From: Shota Zaizen + +commit 996454bc0da84d5a1dedb1a7861823087e01a7ae upstream. + +smb_inherit_dacl() walks the parent directory DACL loaded from the +security descriptor xattr. It verifies that each ACE contains the fixed +SID header before using it, but does not verify that the variable-length +SID described by sid.num_subauth is fully contained in the ACE. + +A malformed inheritable ACE can advertise more subauthorities than are +present in the ACE. compare_sids() may then read past the ACE. +smb_set_ace() also clamps the copied destination SID, but used the +unchecked source SID count to compute the inherited ACE size. That could +advance the temporary inherited ACE buffer pointer and nt_size accounting +past the allocated buffer. + +Fix this by validating the parent ACE SID count and SID length before +using the SID during inheritance. Compute the inherited ACE size from the +copied SID so the size matches the bounded destination SID. Reject the +inherited DACL if size accumulation would overflow smb_acl.size or the +security descriptor allocation size. + +Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") +Signed-off-by: Shota Zaizen +Acked-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/server/smbacl.c | 66 ++++++++++++++++++++++++++++++++++++++----------- + 1 file changed, 52 insertions(+), 14 deletions(-) + +--- a/fs/smb/server/smbacl.c ++++ b/fs/smb/server/smbacl.c +@@ -1025,7 +1025,26 @@ static void smb_set_ace(struct smb_ace * + ace->flags = flags; + ace->access_req = access_req; + smb_copy_sid(&ace->sid, sid); +- ace->size = cpu_to_le16(1 + 1 + 2 + 4 + 1 + 1 + 6 + (sid->num_subauth * 4)); ++ ace->size = cpu_to_le16(1 + 1 + 2 + 4 + 1 + 1 + 6 + ++ (ace->sid.num_subauth * 4)); ++} ++ ++static int smb_append_inherited_ace(struct smb_ace **ace, int *nt_size, ++ u16 *ace_cnt, const struct smb_sid *sid, ++ u8 type, u8 flags, __le32 access_req) ++{ ++ int ace_size; ++ ++ smb_set_ace(*ace, sid, type, flags, access_req); ++ ace_size = le16_to_cpu((*ace)->size); ++ /* pdacl->size is __le16 and includes struct smb_acl. */ ++ if (check_add_overflow(*nt_size, ace_size, nt_size) || ++ *nt_size > U16_MAX - (int)sizeof(struct smb_acl)) ++ return -EINVAL; ++ ++ (*ace_cnt)++; ++ *ace = (struct smb_ace *)((char *)*ace + ace_size); ++ return 0; + } + + int smb_inherit_dacl(struct ksmbd_conn *conn, +@@ -1089,6 +1108,12 @@ int smb_inherit_dacl(struct ksmbd_conn * + if (pace_size > aces_size) + break; + ++ if (parent_aces->sid.num_subauth > SID_MAX_SUB_AUTHORITIES || ++ pace_size < offsetof(struct smb_ace, sid) + ++ CIFS_SID_BASE_SIZE + ++ sizeof(__le32) * parent_aces->sid.num_subauth) ++ break; ++ + aces_size -= pace_size; + + flags = parent_aces->flags; +@@ -1118,22 +1143,24 @@ int smb_inherit_dacl(struct ksmbd_conn * + } + + if (is_dir && creator && flags & CONTAINER_INHERIT_ACE) { +- smb_set_ace(aces, psid, parent_aces->type, inherited_flags, +- parent_aces->access_req); +- nt_size += le16_to_cpu(aces->size); +- ace_cnt++; +- aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size)); ++ rc = smb_append_inherited_ace(&aces, &nt_size, &ace_cnt, ++ psid, parent_aces->type, ++ inherited_flags, ++ parent_aces->access_req); ++ if (rc) ++ goto free_aces_base; + flags |= INHERIT_ONLY_ACE; + psid = creator; + } else if (is_dir && !(parent_aces->flags & NO_PROPAGATE_INHERIT_ACE)) { + psid = &parent_aces->sid; + } + +- smb_set_ace(aces, psid, parent_aces->type, flags | inherited_flags, +- parent_aces->access_req); +- nt_size += le16_to_cpu(aces->size); +- aces = (struct smb_ace *)((char *)aces + le16_to_cpu(aces->size)); +- ace_cnt++; ++ rc = smb_append_inherited_ace(&aces, &nt_size, &ace_cnt, psid, ++ parent_aces->type, ++ flags | inherited_flags, ++ parent_aces->access_req); ++ if (rc) ++ goto free_aces_base; + pass: + parent_aces = (struct smb_ace *)((char *)parent_aces + pace_size); + } +@@ -1143,7 +1170,7 @@ pass: + struct smb_acl *pdacl; + struct smb_sid *powner_sid = NULL, *pgroup_sid = NULL; + int powner_sid_size = 0, pgroup_sid_size = 0, pntsd_size; +- int pntsd_alloc_size; ++ size_t pntsd_alloc_size; + + if (parent_pntsd->osidoffset) { + powner_sid = (struct smb_sid *)((char *)parent_pntsd + +@@ -1156,8 +1183,19 @@ pass: + pgroup_sid_size = 1 + 1 + 6 + (pgroup_sid->num_subauth * 4); + } + +- pntsd_alloc_size = sizeof(struct smb_ntsd) + powner_sid_size + +- pgroup_sid_size + sizeof(struct smb_acl) + nt_size; ++ if (check_add_overflow(sizeof(struct smb_ntsd), ++ (size_t)powner_sid_size, ++ &pntsd_alloc_size) || ++ check_add_overflow(pntsd_alloc_size, ++ (size_t)pgroup_sid_size, ++ &pntsd_alloc_size) || ++ check_add_overflow(pntsd_alloc_size, sizeof(struct smb_acl), ++ &pntsd_alloc_size) || ++ check_add_overflow(pntsd_alloc_size, (size_t)nt_size, ++ &pntsd_alloc_size)) { ++ rc = -EINVAL; ++ goto free_aces_base; ++ } + + pntsd = kzalloc(pntsd_alloc_size, GFP_KERNEL); + if (!pntsd) { diff --git a/queue-6.1/series b/queue-6.1/series index 210925011c..68851dbb41 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -387,3 +387,4 @@ f2fs-compress-change-the-first-parameter-of-page_arr.patch f2fs-compress-fix-uaf-of-f2fs_inode_info-in-f2fs_fre.patch x86-cpu-amd-prevent-improper-isolation-of-shared-resources-in-zen2-s-op-cache.patch exit-sleep-at-task_idle-when-waiting-for-application-core-dump.patch +ksmbd-validate-inherited-ace-sid-length.patch