Linux Security Modules 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 26/41] proc: show UUID and GUID ids in status, accept them for loginuid
Date: Thu, 22 Oct 2026 03:17:51 +0000	[thread overview]
Message-ID: <sashiko-outbox-180927@kernel.org> (raw)
In-Reply-To: <5e8def743ca1ecd53337d7c1ff543cab0ef9b313.1792552161.git.jan.koester@tuxist.de>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] proc: off-by-one TMPBUFLEN in proc_loginuid_write() rejects GUID with newline
- [Medium] proc: torn read of 20-byte loginuid in proc_loginuid_read()
--

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

proc: show UUID and GUID ids in status, accept them for loginuid

This commit adds Uid_r, Gid_r, and Groups_r lines to /proc/<pid>/status to
display user and group ids in text form via kuid_str_munged() and
kgid_str_munged(). It also updates /proc/<pid>/loginuid to accept and
display text-formatted uuid and guid ids alongside classic numeric uids.

> diff --git a/fs/proc/base.c b/fs/proc/base.c
> index 6a39de424f62a..ec3147e7ab05e 100644
> --- a/fs/proc/base.c
> +++ b/fs/proc/base.c
> @@ -1290,20 +1290,26 @@ static const struct file_operations proc_oom_score_adj_operations = {
>  };
>  
>  #ifdef CONFIG_AUDIT
> -#define TMPBUFLEN 11
> +#define TMPBUFLEN KID_STR_LEN
>  static ssize_t proc_loginuid_read(struct file * file, char __user * buf,
>  				  size_t count, loff_t *ppos)
>  {
>  	struct inode * inode = file_inode(file);
>  	struct task_struct *task = get_proc_task(inode);
> +	struct user_namespace *ns = file->f_cred->user_ns;
>  	ssize_t length;
>  	char tmpbuf[TMPBUFLEN];
> +	kuid_t loginuid;
>  
>  	if (!task)
>  		return -ESRCH;
> -	length = scnprintf(tmpbuf, TMPBUFLEN, "%u",
> -			   from_kuid(file->f_cred->user_ns,
> -				     audit_get_loginuid(task)));
> +	loginuid = audit_get_loginuid(task);
> +	/* a UUID or GUID loginuid as text, if @ns can see it */
> +	if (!uid_is_legacy(loginuid) && kuid_has_mapping(ns, loginuid))
> +		length = strlen(kuid_str(loginuid, tmpbuf));
> +	else
> +		length = scnprintf(tmpbuf, TMPBUFLEN, "%u",
> +				   from_kuid(ns, loginuid));

[Severity: Medium]
Can proc_loginuid_read() observe a torn 20-byte kuid_t when reading
task->loginuid concurrently with proc_loginuid_write() ->
audit_set_loginuid()?

In kernel/audit.c:audit_set_loginuid():

	current->sessionid = sessionid;
	current->loginuid = loginuid;

Updating current->loginuid is an unsynchronized 20-byte struct store, and
audit_get_loginuid(task) in proc_loginuid_read() copies task->loginuid from
a potentially running target task without a lock or seqcount retry loop.

When transitioning between a legacy id (such as INVALID_UID) and a uuid or
guid id, a concurrent reader of /proc/<pid>/loginuid could see the new
.type before all 16 bytes of .uuid/.guid are written (or after .legacy is
overwritten when unsetting), causing kuid_str() to format a corrupted uuid
or guid string. Conversely, seeing the old KID_LEGACY .type with the first
4 bytes of the new .uuid/.guid already stored would cause from_kuid() to
return a bogus numeric uid to userspace.

Would a seqcount or lock around task->loginuid be needed here to prevent
torn reads?

>  	put_task_struct(task);
>  	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
>  }
> @@ -1312,7 +1318,7 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
>  				   size_t count, loff_t *ppos)
>  {
>  	struct inode * inode = file_inode(file);
> -	uid_t loginuid;
> +	char tmpbuf[TMPBUFLEN];
>  	kuid_t kloginuid;
>  	int rv;
>  
> @@ -1332,16 +1338,20 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
>  		return -EINVAL;
>  	}
>  
> -	rv = kstrtou32_from_user(buf, count, 10, &loginuid);
> -	if (rv < 0)
> -		return rv;
> +	/* a decimal uid, a UUID or a GUID in braces */
> +	if (count >= sizeof(tmpbuf))
> +		return -EINVAL;
> +	if (copy_from_user(tmpbuf, buf, count))
> +		return -EFAULT;
> +	tmpbuf[count] = '\0';
>  
> -	/* is userspace tring to explicitly UNSET the loginuid? */
> -	if (loginuid == AUDIT_UID_UNSET) {
> -		kloginuid = INVALID_UID;
> -	} else {
> -		kloginuid = make_kuid(file->f_cred->user_ns, loginuid);
> -		if (!uid_valid(kloginuid))
> +	kloginuid = make_kuid_str(file->f_cred->user_ns, tmpbuf);

[Severity: Medium]
Does this size check in proc_loginuid_write() reject a guid in braces when
written with a trailing newline?

In include/linux/uidgid.h, KID_STR_LEN is 39, which is the exact size of a
38-character guid in braces ("{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}") plus
the terminating nul byte.

Meanwhile, make_kuid_str() -> kid_r_from_str() in kernel/uidgid_r.c is
designed to accept an optional trailing newline before checking the length
against KID_STR_LEN:

	if (len && str[len - 1] == '\n')
		len--;
	if (!len || len >= sizeof(buf))
		return -EINVAL;

Because TMPBUFLEN is defined as KID_STR_LEN (39), writing a 38-byte guid in
braces followed by '\n' passes count == 39 to proc_loginuid_write(), which
hits count >= sizeof(tmpbuf) and returns -EINVAL before reaching
make_kuid_str().

Should tmpbuf in proc_loginuid_write() (or TMPBUFLEN) be sized to
KID_STR_LEN + 1 so that a guid in braces with a trailing newline is
accepted just like decimal uids and uuids with a trailing newline?

> +	if (!uid_valid(kloginuid)) {
> +		u32 loginuid;
> +
> +		/* is userspace tring to explicitly UNSET the loginuid? */
> +		if (kstrtou32(tmpbuf, 10, &loginuid) ||
> +		    loginuid != AUDIT_UID_UNSET)
>  			return -EINVAL;
>  	}
>

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

  reply	other threads:[~2026-10-22  3:17 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 [this message]
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
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-180927@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