Audit system development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Jan Koester" <jan.koester@tuxist.de>,
	"Christian Brauner" <brauner@kernel.org>,
	"Alexander Viro" <viro@zeniv.linux.org.uk>,
	"Serge E. Hallyn" <serge@hallyn.com>
Cc: "Jan Kara" <jack@suse.cz>, "Theodore Y. Ts'o" <tytso@mit.edu>,
	"Paul Moore" <paul@paul-moore.com>,
	"Arnd Bergmann" <arnd@arndb.de>,
	linux-security-module@vger.kernel.org,
	linux-ext4@vger.kernel.org, audit@vger.kernel.org,
	keyrings@vger.kernel.org, "Chuck Lever" <cel@kernel.org>,
	"Jeff Layton" <jlayton@kernel.org>,
	"Anna Schumaker" <anna@kernel.org>
Subject: Re: [RFC PATCH v2 39/41] ksmbd: log in UUID and GUID users and map them to SIDs
Date: Thu, 22 Oct 2026 03:18:07 +0000	[thread overview]
Message-ID: <sashiko-outbox-180940@kernel.org> (raw)
In-Reply-To: <73dfe9aab6c5dd8152fa494d53f470f3bea53127.1792552161.git.jan.koester@tuxist.de>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] ksmbd: sid_to_id() bypasses make_kuid_r() validation for UUID/GUID SIDs
- [High] ksmbd: ksmbd_alloc_user() falls back to resp uid/gid when resp_ext is NULL
- [Low] ksmbd: unused uid and gid fields and helpers in struct ksmbd_user
--

commit a1ea85f35f595431966b4e9bd815708cd849c5bc
Author: Jan Koester <jan.koester@tuxist.de>

ksmbd: log in UUID and GUID users and map them to SIDs

This commit adds support for logging in UUID and GUID users and groups via
ksmbd_login_response_ext and mapping their kuid_t and kgid_t values to and
from S-1-22-<kind>-w0-w1-w2-w3 SIDs in security descriptors, POSIX ACLs,
and durable handle owners.

[ ... ]

> diff --git a/fs/smb/server/mgmt/user_config.c b/fs/smb/server/mgmt/user_config.c
> index 5efc3d7455b99..cb175a4c78d83 100644
> --- a/fs/smb/server/mgmt/user_config.c
> +++ b/fs/smb/server/mgmt/user_config.c
> @@ -56,6 +56,8 @@ struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp,
>  	user->flags = resp->status;
>  	user->gid = resp->gid;
>  	user->uid = resp->uid;
> +	user->kuid = make_kuid(&init_user_ns, resp->uid);
> +	user->kgid = make_kgid(&init_user_ns, resp->gid);
>  	user->passkey_sz = resp->hash_sz;
>  	user->passkey = kmalloc(resp->hash_sz, KSMBD_DEFAULT_GFP);
>  	if (user->passkey)
> @@ -68,12 +70,38 @@ struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp,
>  		goto err_free;
>  
>  	if (resp_ext) {
> -		user->sgid = kmemdup(resp_ext->____payload,
> -				     resp_ext->ngroups * sizeof(gid_t),
> +		int i;
> +
> +		if (resp_ext->flags & KSMBD_LOGIN_EXT_ID_R) {
> +			/* the user's ids may be UUIDs or GUIDs */
> +			user->kuid = make_kuid_r(&init_user_ns, &resp_ext->uid_r);
> +			user->kgid = make_kgid_r(&init_user_ns, &resp_ext->gid_r);
> +			if (!uid_valid(user->kuid) || !gid_valid(user->kgid))
> +				goto err_free;
> +			user->uid = from_kuid_munged(&init_user_ns, user->kuid);
> +			user->gid = from_kgid_munged(&init_user_ns, user->kgid);
> +		}

[Severity: High]
What happens in ksmbd_alloc_user() in fs/smb/server/mgmt/user_config.c if
resp->status has KSMBD_USER_FLAG_EXTENSION set, but fetching the login
extension via ksmbd_ipc_login_request_ext() fails and returns NULL?

Both callers pass resp_ext directly to ksmbd_alloc_user() without checking
whether the second IPC request succeeded:

fs/smb/server/mgmt/user_config.c:ksmbd_login_user() {
	if (resp->status & KSMBD_USER_FLAG_EXTENSION)
		resp_ext = ksmbd_ipc_login_request_ext(account);

	user = ksmbd_alloc_user(resp, resp_ext);
}

fs/smb/server/auth.c:ksmbd_krb5_authenticate() {
	if (resp->login_response.status & KSMBD_USER_FLAG_EXTENSION)
		resp_ext = ksmbd_ipc_login_request_ext(resp->login_response.account);

	user = ksmbd_alloc_user(&resp->login_response, resp_ext);
}

Per the comment on struct ksmbd_login_response_ext in
fs/smb/server/ksmbd_netlink.h, resp->uid and resp->gid in the base login
response are ignored when KSMBD_LOGIN_EXT_ID_R is used. However, if
ksmbd_ipc_login_request_ext() returns NULL (for example on an IPC error,
allocation failure, or validation failure in ipc_validate_msg()), the
if (resp_ext) block is skipped and ksmbd_alloc_user() still succeeds using
user->kuid and user->kgid initialized from resp->uid and resp->gid.

If userspace left resp->uid and resp->gid zeroed in the base response, the
session will log in as GLOBAL_ROOT_UID and GLOBAL_ROOT_GID (keeping
filesystem capabilities in __ksmbd_override_fsids()). If resp->uid or
resp->gid is -1 (or when KSMBD_LOGIN_EXT_ID_R is not set), user->kuid or
user->kgid becomes INVALID_UID or INVALID_GID because uid_valid() and
gid_valid() are only checked inside the KSMBD_LOGIN_EXT_ID_R branch.

Should ksmbd_alloc_user() reject the login when
resp->status & KSMBD_USER_FLAG_EXTENSION is set but resp_ext is NULL, and
also check uid_valid(user->kuid) and gid_valid(user->kgid) when
KSMBD_LOGIN_EXT_ID_R is not set?

[ ... ]

> diff --git a/fs/smb/server/mgmt/user_config.h b/fs/smb/server/mgmt/user_config.h
> index cc460b4ff7d39..e55470e008f50 100644
> --- a/fs/smb/server/mgmt/user_config.h
> +++ b/fs/smb/server/mgmt/user_config.h
> @@ -13,13 +13,15 @@ struct ksmbd_user {
>  
>  	unsigned int		uid;
>  	unsigned int		gid;
> +	kuid_t			kuid;	/* the user: uid, or a UUID or GUID */
> +	kgid_t			kgid;
>  
>  	char			*name;
>  
>  	size_t			passkey_sz;
>  	char			*passkey;
>  	int			ngroups;
> -	gid_t			*sgid;
> +	kgid_t			*sgid;
>  };
>  
>  static inline bool user_guest(struct ksmbd_user *user)

[Severity: Low]
This isn't a bug, but now that smb2_open(), process_query_dir_entries(),
__ksmbd_override_fsids(), ksmbd_vfs_set_durable_owner(), and
ksmbd_vfs_compare_durable_owner() all use user->kuid and user->kgid, are
the 32-bit uid and gid fields in struct ksmbd_user (and the user_uid() and
user_gid() helpers in fs/smb/server/mgmt/user_config.h) still needed, or
could they be dropped now that they have no remaining readers?

[ ... ]

> diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c
> index 1fad6ccf3a72a..126264cc0734e 100644
> --- a/fs/smb/server/smbacl.c
> +++ b/fs/smb/server/smbacl.c

[ ... ]

> @@ -279,6 +341,42 @@ static int sid_to_id(struct mnt_idmap *idmap,
>  		return -EIO;
>  	}
>  
> +	{
> +		u8 id[16];
> +		u32 kind = sid_to_id_r(psid, id);
> +
> +		if (kind && sidtype == SIDOWNER &&
> +		    (kind == SID_UNIX_UUID_USER || kind == SID_UNIX_GUID_USER)) {
> +			kuid_t uid;
> +
> +			if (kind == SID_UNIX_UUID_USER)
> +				uid = KUIDT_INIT_UUID(*(uuid_t *)id);
> +			else
> +				uid = KUIDT_INIT_GUID(*(guid_t *)id);
> +			uid = from_vfsuid(idmap, &init_user_ns, VFSUIDT_INIT(uid));
> +			if (!uid_valid(uid))
> +				return -EINVAL;
> +			fattr->cf_uid = uid;
> +			return 0;
> +		}
> +		if (kind && sidtype != SIDOWNER &&
> +		    (kind == SID_UNIX_UUID_GROUP || kind == SID_UNIX_GUID_GROUP)) {
> +			kgid_t gid;
> +
> +			if (kind == SID_UNIX_UUID_GROUP)
> +				gid = KGIDT_INIT_UUID(*(uuid_t *)id);
> +			else
> +				gid = KGIDT_INIT_GUID(*(guid_t *)id);
> +			gid = from_vfsgid(idmap, &init_user_ns, VFSGIDT_INIT(gid));
> +			if (!gid_valid(gid))
> +				return -EINVAL;
> +			fattr->cf_gid = gid;
> +			return 0;
> +		}
> +		if (kind)
> +			return -EINVAL;
> +	}

[Severity: High]
Can sid_to_id() in fs/smb/server/smbacl.c allow an SMB client to persist
malformed UUIDs or nil GUIDs into inode ownership and POSIX ACLs?

When a client sends an SMB2_SET_INFO or SMB2_CREATE security descriptor
containing an S-1-22-<kind>-w0-w1-w2-w3 SID (via set_info_sec() ->
parse_sec_desc() / parse_dacl() -> sid_to_id()), sid_to_id() builds the
kuid_t or kgid_t directly with KUIDT_INIT_UUID(), KUIDT_INIT_GUID(),
KGIDT_INIT_UUID(), and KGIDT_INIT_GUID() instead of calling make_kuid_r()
and make_kgid_r().

Unlike make_kuid_r() and make_kgid_r(), which validate the 16-byte payload
via kid_r_valid() in kernel/uidgid_r.c:

kernel/uidgid_r.c:kid_r_valid() {
	switch (id->type) {
	...
	case UID_R_UUID:
		return (id->uuid[6] >> 4) == 4 && (id->uuid[8] & 0xc0) == 0x80;
	case UID_R_GUID:
		return memchr_inv(id->guid, 0, UID_R_SIZE);
	}
	return false;
}

the uid_valid() and gid_valid() checks in include/linux/uidgid.h
unconditionally return true for any KID_UUID or KID_GUID:

include/linux/uidgid.h:uid_valid() {
	return !uid_is_legacy(uid) || __kuid_val(uid) != (uid_t) -1;
}

As a result, a client can pass a non-v4/non-RFC-9562 UUID (such as
S-1-22-3-0-0-0-0) or a nil GUID (S-1-22-5-0-0-0-0) and have it stored on
 the inode or in POSIX ACL xattrs, causing subsequent userspace operations
that validate via kid_r_valid() (such as chown_r() or setxattr() on POSIX
ACLs) to fail with -EINVAL.

Should sid_to_id() construct these IDs via make_kuid_r() and make_kgid_r()
so that invalid UUID and GUID payloads are rejected?

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1792552161.git.jan.koester@tuxist.de?part=39

  reply	other threads:[~2026-10-22  3:18 UTC|newest]

Thread overview: 89+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-21  3:15 [RFC PATCH v2 00/41] UUID and GUID user and group ids (*_r system calls) Jan Koester
2026-10-21  3:15 ` [RFC PATCH v2 01/41] uuid: move uuid_t and guid_t into <linux/uuid_types.h> Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 02/41] uapi: add <linux/uidgid_r.h> for 128 bit capable user and group ids Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 03/41] uidgid: add uid_is_legacy() and gid_is_legacy() Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 04/41] net: sock: read sk_uid through a seqcount Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 05/41] af_unix: keep sender ids in skb->cb only when they are classic ids Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 06/41] netlink: keep classic sender ids in skb->cb Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 07/41] Bluetooth: " Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 08/41] smb: client: use __kuid_val() for the unix SIDs of the caller Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 09/41] uidgid: let kuid_t and kgid_t hold a UUID or a GUID Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 10/41] uidgid: convert between kernel ids and the ids of the *_r system calls Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 11/41] fscrypt: show the whole uid in the description of user key claims Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 12/41] keys: name per-user keyrings of UUID and GUID users by the whole uid Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 13/41] ublk: refuse unprivileged devices to UUID and GUID users Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 14/41] nfsd: don't hand out uid 0 for read layouts of UUID-owned files Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 15/41] SUNRPC: name UUID and GUID users to gssd as uid_r= Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 16/41] ecryptfs: hash daemons by kuid_hash() Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 17/41] quota: don't account UUID and GUID owners Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 18/41] fs: keep UUID and GUID owners off filesystems that can't store them Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 19/41] cred: add the *_r variants of the get/set*id() system calls Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 20/41] groups: add getgroups_r() and setgroups_r() Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 21/41] fs: add chown_r(), lchown_r(), fchown_r() and fchownat_r() Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 22/41] arch: wire up the *_r uid and gid system calls Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 23/41] statx: report UUID and GUID owners Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 24/41] shmem, ramfs: allow " Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 25/41] uidgid: parse and print ids in their text form Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 26/41] proc: show UUID and GUID ids in status, accept them for loginuid Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 27/41] audit: log UUID and GUID ids in full Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 28/41] net: add SO_PEERCRED_R, SO_PEERGROUPS_R and SCM_CREDENTIALS_R Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 29/41] signal: report the sender's UUID or GUID uid in si_uid_r Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 30/41] ipc: add IPC_STAT_R and IPC_SET_R Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 31/41] ext4: add the uid_r feature for UUID and GUID owners Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 32/41] ext4: let uid_r be turned on while the filesystem is mounted Jan Koester
2026-10-22  3:17   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 33/41] posix_acl: support UUID and GUID entries Jan Koester
2026-10-22  3:18   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 34/41] ext4: store ACLs with UUID and GUID entries on uid_r filesystems Jan Koester
2026-10-22  3:18   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 35/41] Documentation: describe UUID and GUID user and group ids Jan Koester
2026-10-22  3:18   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 36/41] selftests: add tests for UUID and GUID ids Jan Koester
2026-10-22  3:18   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 37/41] ovl: allow UUID and GUID owners when the upper layer does Jan Koester
2026-10-22  3:18   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 38/41] devpts: allow UUID and GUID owners Jan Koester
2026-10-22  3:18   ` sashiko-bot
2026-10-21  3:15 ` [RFC PATCH v2 39/41] ksmbd: log in UUID and GUID users and map them to SIDs Jan Koester
2026-10-22  3:18   ` sashiko-bot [this message]
2026-10-21  3:16 ` [RFC PATCH v2 40/41] nfsd, nfs: carry UUID and GUID owners as their text form Jan Koester
2026-10-21 17:35   ` Chuck Lever
2026-10-22  2:52     ` Takeshi Nishimura
2026-10-22  3:18   ` sashiko-bot
2026-10-21  3:16 ` [RFC PATCH v2 41/41] Documentation: uid_r: describe SMB and NFSv4 Jan Koester
2026-10-22  3:18   ` sashiko-bot
2026-10-21  3:20 ` [RFC PATCH v2 00/41] UUID and GUID user and group ids (*_r system calls) jan Koester
2026-10-21 14:26 ` Adding dreaded Windows SID-style, or. Repeating history, the bad chapters. UUID/GUIDRe: " Lionel Cons
2026-10-22 17:00 ` Casey Schaufler
2026-10-22 18:26   ` Theodore Tso

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=sashiko-outbox-180940@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=anna@kernel.org \
    --cc=arnd@arndb.de \
    --cc=audit@vger.kernel.org \
    --cc=brauner@kernel.org \
    --cc=cel@kernel.org \
    --cc=jack@suse.cz \
    --cc=jan.koester@tuxist.de \
    --cc=jlayton@kernel.org \
    --cc=keyrings@vger.kernel.org \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=paul@paul-moore.com \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=serge@hallyn.com \
    --cc=tytso@mit.edu \
    --cc=viro@zeniv.linux.org.uk \
    /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