All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.