aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorNamjae Jeon <linkinjeon@kernel.org>2026-07-04 11:07:51 +0900
committerSteve French <stfrench@microsoft.com>2026-07-22 09:54:10 -0500
commit5152c6d49e3fd4e9f2e857c57527aead752f1f87 (patch)
treeb2187df63b539c9002e79b35dc84fb8a2da87e1e
parentksmbd: restore DACL size on check_add_overflow() to avoid malformed ACL (diff)
ksmbd: validate ACE size against SID sub-authorities
set_ntacl_dacl() validates sid.num_subauth before copying an ACE, but does not verify that the declared ACE size contains all sub-authorities described by that field. An undersized ACE can therefore be copied and later make the POSIX ACL deduplication walk inspect data beyond the copied ACE boundary. The existing initial bound check is also too small. It only ensures that the ACE size field is accessible before set_ntacl_dacl() reads sid.num_subauth farther into the input buffer. Require enough input for the fixed SID header before accessing num_subauth, reject ACEs smaller than that header, and skip ACEs whose declared size cannot contain the complete SID. This makes the validation consistent with the other ACE walk paths. Reported-by: LocalHost <localhost.detect@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
-rw-r--r--fs/smb/server/smbacl.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c
index f285b4f24a5b..c13f07a09ab8 100644
--- a/fs/smb/server/smbacl.c
+++ b/fs/smb/server/smbacl.c
@@ -756,15 +756,22 @@ static void set_ntacl_dacl(struct mnt_idmap *idmap,
for (i = 0; i < nt_num_aces; i++) {
unsigned short nt_ace_size;
- if (offsetof(struct smb_ace, access_req) > aces_size)
+ if (aces_size < offsetof(struct smb_ace, sid) +
+ CIFS_SID_BASE_SIZE)
break;
nt_ace_size = le16_to_cpu(ntace->size);
- if (nt_ace_size > aces_size)
+ if (nt_ace_size > aces_size ||
+ nt_ace_size < offsetof(struct smb_ace, sid) +
+ CIFS_SID_BASE_SIZE)
break;
if (ntace->sid.num_subauth == 0 ||
- ntace->sid.num_subauth > SID_MAX_SUB_AUTHORITIES)
+ ntace->sid.num_subauth > SID_MAX_SUB_AUTHORITIES ||
+ nt_ace_size < offsetof(struct smb_ace, sid) +
+ CIFS_SID_BASE_SIZE +
+ sizeof(__le32) *
+ ntace->sid.num_subauth)
goto next_ace;
memcpy((char *)pndace + size, ntace, nt_ace_size);