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 29/41] signal: report the sender's UUID or GUID uid in si_uid_r
Date: Thu, 22 Oct 2026 03:17:55 +0000 [thread overview]
Message-ID: <sashiko-outbox-180930@kernel.org> (raw)
In-Reply-To: <59988b6ac15fa727c7f5d14d5342ceba4d6e595f.1792552161.git.jan.koester@tuxist.de>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] signal: broken userns UID mapping in send_signal_locked() and callers
- [Medium] bpf: missing siginfo_set_kernel_uid() call in bpf_send_signal_common()
--
commit 3fc8400fa91445ed3a591553195996d33af32cb3
Author: Jan Koester <jan.koester@tuxist.de>
signal: report the sender's UUID or GUID uid in si_uid_r
This commit adds si_uid_r (__kernel_uid_r_t) at offset 96 in siginfo_t and
compat_siginfo_t, along with ssi_uid_r in signalfd_siginfo, to report the
sender's UUID or GUID UID for signals and waitid(). It introduces
siginfo_set_uid() and siginfo_set_kernel_uid() to populate and translate
si_uid and si_uid_r across signal generation, delivery, and wait paths.
> diff --git a/include/linux/signal.h b/include/linux/signal.h
> index f19816832f055..928e67e283b60 100644
> --- a/include/linux/signal.h
> +++ b/include/linux/signal.h
> @@ -6,6 +6,7 @@
> #include <linux/list.h>
> #include <linux/signal_types.h>
> #include <linux/string.h>
> +#include <linux/uidgid.h>
>
> struct task_struct;
>
> @@ -23,6 +24,27 @@ static inline void clear_siginfo(kernel_siginfo_t *info)
> memset(info, 0, sizeof(*info));
> }
>
> +struct user_namespace;
> +
> +/*
> + * Sets si_uid and si_uid_r to @uid as seen from @ns (the receiver's user
> + * namespace), the overflow id if it has no mapping there.
> + */
> +static inline void siginfo_set_uid(kernel_siginfo_t *info,
> + struct user_namespace *ns, kuid_t uid)
> +{
> + info->si_uid = from_kuid_munged(ns, uid);
> + from_kuid_r_munged(ns, uid, &info->si_uid_r);
> +}
> +
> +/* si_uid and si_uid_r of a signal from the kernel: 0 */
> +static inline void siginfo_set_kernel_uid(kernel_siginfo_t *info)
> +{
> + info->si_uid = 0;
> + memset(&info->si_uid_r, 0, sizeof(info->si_uid_r));
> + info->si_uid_r.type = UID_R_LEGACY;
> +}
[Severity: Medium]
Should bpf_send_signal_common() in kernel/trace/bpf_trace.c also call
siginfo_set_kernel_uid(&info) when sending a signal to a specific task?
When a BPF program invokes bpf_send_signal_task() with a non-NULL task,
bpf_send_signal_common() takes the else branch and initializes info manually:
kernel/trace/bpf_trace.c:bpf_send_signal_common() {
if (!task) {
task = current;
siginfo = SEND_SIG_PRIV;
} else {
clear_siginfo(&info);
info.si_signo = sig;
info.si_errno = 0;
info.si_code = SI_KERNEL;
info.si_pid = 0;
info.si_uid = 0;
info.si_value.sival_ptr = (void __user __force *)(unsigned long)value;
siginfo = &info;
}
}
Because info.si_uid = 0 is set directly after clear_siginfo(&info),
info.si_uid_r remains UID_R_NONE instead of UID_R_LEGACY with uid 0, whereas
calling bpf_send_signal() or bpf_send_signal_thread() (where task is NULL)
uses SEND_SIG_PRIV and sets info.si_uid_r via siginfo_set_kernel_uid().
[ ... ]
> diff --git a/ipc/mqueue.c b/ipc/mqueue.c
> index d1dd36a651b0d..f0a319ed97515 100644
> --- a/ipc/mqueue.c
> +++ b/ipc/mqueue.c
> @@ -802,8 +802,8 @@ static void __do_notify(struct mqueue_inode_info *info)
> /* map current pid/uid into info->owner's namespaces */
> sig_i.si_pid = task_tgid_nr_ns(current,
> ns_of_pid(info->notify_owner));
> - sig_i.si_uid = from_kuid_munged(info->notify_user_ns,
> - current_uid());
> + siginfo_set_uid(&sig_i, info->notify_user_ns,
> + current_uid());
> /*
> * We can't use kill_pid_info(), this signal should
> * bypass check_kill_permission(). It is from kernel
[ ... ]
> diff --git a/kernel/signal.c b/kernel/signal.c
> index d31ebcb6ed4db..af0793d04b640 100644
> --- a/kernel/signal.c
> +++ b/kernel/signal.c
[ ... ]
> @@ -1229,6 +1228,13 @@ int send_signal_locked(int sig, struct kernel_siginfo *info,
> info = &rewritten;
> uid = make_kuid(current_user_ns(), info->si_uid);
> rewritten.si_uid = from_kuid_munged(t_user_ns, uid);
> + if (rewritten.si_uid_r.type != UID_R_NONE) {
> + kuid_t uid_r = make_kuid_r(current_user_ns(),
> + &rewritten.si_uid_r);
> +
> + from_kuid_r_munged(t_user_ns, uid_r,
> + &rewritten.si_uid_r);
> + }
> }
> rcu_read_unlock();
> #endif
[Severity: High]
Can this cross-user-namespace translation in send_signal_locked() corrupt
both si_uid and si_uid_r in several signal delivery paths?
First, in send_signal_locked(), rewritten.si_uid is still derived from the
32-bit info->si_uid via make_kuid(current_user_ns(), info->si_uid) rather
than from uid_r. When a process with a UUID or GUID UID in init_user_ns
signals a task in a child user namespace t_user_ns (via
prepare_kill_siginfo() in tkill(), tgkill(), or pidfd_send_signal() with
info == NULL, or via rt_sigqueueinfo()), info->si_uid has already been munged
to overflowuid (65534). make_kuid(&init_user_ns, 65534) then fabricates the
legacy host UID KUIDT_INIT(65534). If t_user_ns maps legacy host UID 65534 to
a valid container UID, rewritten.si_uid is set to that container UID instead
of overflowuid, while rewritten.si_uid_r is munged to overflowuid.
Second, prepare_kill_siginfo() in kernel/signal.c pre-maps current_uid() into
current_user_ns() before send_signal_locked() knows the target's user
namespace:
kernel/signal.c:prepare_kill_siginfo() {
clear_siginfo(info);
info->si_signo = sig;
info->si_errno = 0;
info->si_code = (type == PIDTYPE_PID) ? SI_TKILL : SI_USER;
info->si_pid = task_tgid_vnr(current);
siginfo_set_uid(info, current_user_ns(), current_uid());
}
If a task with a UUID or GUID UID enters a child user namespace via
unshare(CLONE_NEWUSER) or setns() and calls tkill(), tgkill(), or
pidfd_send_signal() (with info == NULL) targeting a task in init_user_ns,
siginfo_set_uid() in prepare_kill_siginfo() immediately munges info->si_uid_r
to UID_R_LEGACY / overflowuid because current_user_ns() != &init_user_ns.
When send_signal_locked() subsequently translates from current_user_ns() to
t_user_ns (&init_user_ns), the original UUID or GUID has already been lost.
Third, both do_notify_parent_cldstop() in kernel/signal.c and __do_notify()
in ipc/mqueue.c already translate the sender's kuid_t into the receiver's
user namespace via siginfo_set_uid(), but then pass the resulting siginfo to
send_signal_locked():
kernel/signal.c:do_notify_parent_cldstop()
-> siginfo_set_uid(&info, task_cred_xxx(parent, user_ns), task_uid(tsk))
-> send_signal_locked(SIGCHLD, &info, parent, PIDTYPE_TGID)
ipc/mqueue.c:__do_notify()
-> siginfo_set_uid(&sig_i, info->notify_user_ns, current_uid())
-> do_send_sig_info(info->notify.sigev_signo, &sig_i, task, PIDTYPE_TGID)
-> send_signal_locked(sig, info, p, type)
When current_user_ns() != t_user_ns, send_signal_locked() translates si_uid
and si_uid_r a second time assuming they were formatted in current_user_ns().
For example, if a child or mqueue sender with a UUID or GUID UID is in a
child user namespace and the parent or notify_owner is in init_user_ns,
siginfo_set_uid() writes the UUID or GUID into si_uid_r, and
send_signal_locked() then calls make_kuid_r(current_user_ns(), ...), which
fails in kid_r_to_128() and returns INVALID_UID, overwriting the valid UUID
or GUID with overflowuid.
[ ... ]
完美! Let's double check everything before finalizing. Everything adheres strictly to the guidelines.
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1792552161.git.jan.koester@tuxist.de?part=29
next prev parent 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
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 [this message]
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-180930@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