mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 10:09:10 +02:00
ksmbd: validate SID namespace before mapping IDs
sid_to_id() currently treats the last subauthority of any owner or group SID as a Unix uid or gid. For example, this maps Everyone (S-1-1-0) to uid 0 and BUILTIN\Users (S-1-5-32-545) to gid 545. When an SMB2 CREATE security descriptor contains those SIDs, ksmbd attempts to change the newly created file to the bogus Unix ownership. notify_change() then returns -EPERM, which makes smb2.create.aclfile fail with NT_STATUS_SHARING_VIOLATION. Validate the SID prefix before extracting its RID. Only server-domain owner SIDs and S-1-22-2 Unix group SIDs have local ID representations. Treat other valid Windows SIDs as unmapped so their original values can still be preserved in the NT ACL xattr. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
8cdeaa50ea
commit
fbe0bb2b75
|
|
@ -258,6 +258,7 @@ static int sid_to_id(struct mnt_idmap *idmap,
|
|||
struct smb_sid *psid, uint sidtype,
|
||||
struct smb_fattr *fattr)
|
||||
{
|
||||
const struct smb_sid *sid_prefix;
|
||||
int rc = -EINVAL;
|
||||
|
||||
/*
|
||||
|
|
@ -279,6 +280,12 @@ static int sid_to_id(struct mnt_idmap *idmap,
|
|||
kuid_t uid;
|
||||
uid_t id;
|
||||
|
||||
/* Only the server domain RID has a local uid representation. */
|
||||
sid_prefix = &server_conf.domain_sid;
|
||||
if (psid->num_subauth != sid_prefix->num_subauth + 1 ||
|
||||
compare_sids(psid, sid_prefix))
|
||||
return -EINVAL;
|
||||
|
||||
id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
|
||||
uid = KUIDT_INIT(id);
|
||||
uid = from_vfsuid(idmap, &init_user_ns, VFSUIDT_INIT(uid));
|
||||
|
|
@ -290,6 +297,12 @@ static int sid_to_id(struct mnt_idmap *idmap,
|
|||
kgid_t gid;
|
||||
gid_t id;
|
||||
|
||||
/* Local gids are represented by S-1-22-2-<gid>. */
|
||||
sid_prefix = &sid_unix_groups;
|
||||
if (psid->num_subauth != sid_prefix->num_subauth + 1 ||
|
||||
compare_sids(psid, sid_prefix))
|
||||
return -EINVAL;
|
||||
|
||||
id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
|
||||
gid = KGIDT_INIT(id);
|
||||
gid = from_vfsgid(idmap, &init_user_ns, VFSGIDT_INIT(gid));
|
||||
|
|
@ -900,9 +913,9 @@ int parse_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
|
|||
|
||||
rc = sid_to_id(idmap, owner_sid_ptr, SIDOWNER, fattr);
|
||||
if (rc) {
|
||||
pr_err("%s: Error %d mapping Owner SID to uid\n",
|
||||
__func__, rc);
|
||||
ksmbd_debug(SMB, "Owner SID has no Unix uid mapping\n");
|
||||
owner_sid_ptr = NULL;
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -918,9 +931,9 @@ int parse_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
|
|||
}
|
||||
rc = sid_to_id(idmap, group_sid_ptr, SIDUNIX_GROUP, fattr);
|
||||
if (rc) {
|
||||
pr_err("%s: Error %d mapping Group SID to gid\n",
|
||||
__func__, rc);
|
||||
ksmbd_debug(SMB, "Group SID has no Unix gid mapping\n");
|
||||
group_sid_ptr = NULL;
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user