From 149b192e376d746bf7b8e1e02541c2256c3b17f0 Mon Sep 17 00:00:00 2001 From: Bill Roberts Date: Mon, 15 Jun 2026 15:03:25 -0500 Subject: [PATCH 1/4] lsm: clarify security_task_prctl() hook documentation The task_prctl hook comment incorrectly described the hook as checking whether a prctl operation is allowed. In reality, the hook exists for LSMs to handle LSM-specific prctl operations. Update the function description and kernel-doc comment to reflect the actual behavior. The old wording appears to have been copied from other permission-check hooks despite differing semantics. Signed-off-by: Bill Roberts Acked-by: Casey Schaufler Reviewed-by: Serge Hallyn [PM: subj tweak, comment tweak -> "prctl to prctl()" ] Signed-off-by: Paul Moore --- security/security.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/security/security.c b/security/security.c index 71aea8fdf014..2ee276ab15c5 100644 --- a/security/security.c +++ b/security/security.c @@ -3301,15 +3301,14 @@ int security_task_kill(struct task_struct *p, struct kernel_siginfo *info, } /** - * security_task_prctl() - Check if a prctl op is allowed + * security_task_prctl() - Handle an LSM specific prctl() call * @option: operation * @arg2: argument * @arg3: argument * @arg4: argument * @arg5: argument * - * Check permission before performing a process control operation on the - * current process. + * Handle lsm specific prctl() operations. * * Return: Return -ENOSYS if no-one wanted to handle this op, any other value * to cause prctl() to return immediately with that value. From ef2d3e4635761b0af2bf1b89a2252e42a3bf37f1 Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Fri, 3 Jul 2026 06:57:01 +0000 Subject: [PATCH 2/4] rust: task: clarify comments on task UID accessors Linux has separate subjective and objective task credentials, see the comment above `struct cred`. Clarify which accessor functions operate on which set of credentials. Also document that Task::euid() is a very weird operation. You can see how weird it is by grepping for task_euid() in the history - binder was its only user. Task::euid() obtains the objective effective UID - it looks at the credentials of the task for purposes of acting on it as an object, but then accesses the effective UID (which the credentials.7 man page describes as "[...] used by the kernel to determine the permissions that the process will have when accessing shared resources [...]"). For context: Arguably, binder's use of task_euid() is a theoretical security problem, which only has no impact on Android because Android has no setuid binaries executable by apps. commit 29bc22ac5e5b ("binder: use euid from cred instead of using task") originally fixed that by removing that only user of task_euid(), but the fix got reverted in commit c21a80ca0684 ("binder: fix test regression due to sender_euid change") because some Android test started failing. It was since fixed again by commit 65b672152289 ("binder: use current_euid() for transaction sender identity"), which uses current_euid() instead. Signed-off-by: Jann Horn Reviewed-by: Gary Guo Signed-off-by: Alice Ryhl Signed-off-by: Paul Moore --- rust/kernel/task.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/rust/kernel/task.rs b/rust/kernel/task.rs index 38273f4eedb5..eabd65bfde12 100644 --- a/rust/kernel/task.rs +++ b/rust/kernel/task.rs @@ -210,14 +210,17 @@ pub fn pid(&self) -> Pid { unsafe { *ptr::addr_of!((*self.as_ptr()).pid) } } - /// Returns the UID of the given task. + /// Returns the objective real UID of the given task. #[inline] pub fn uid(&self) -> Kuid { // SAFETY: It's always safe to call `task_uid` on a valid task. Kuid::from_raw(unsafe { bindings::task_uid(self.as_ptr()) }) } - /// Returns the effective UID of the given task. + /// Returns the objective effective UID of the given task. + /// + /// You should probably not be using this; the effective UID is normally + /// only relevant in subjective credentials. #[inline] pub fn euid(&self) -> Kuid { // SAFETY: It's always safe to call `task_euid` on a valid task. @@ -371,7 +374,7 @@ fn eq(&self, other: &Self) -> bool { impl Eq for Task {} impl Kuid { - /// Get the current euid. + /// Get the current subjective effective UID. #[inline] pub fn current_euid() -> Kuid { // SAFETY: Just an FFI call. From 15c1f17979712407a4a71f2129f89ecd625ccbe8 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Fri, 3 Jul 2026 06:57:02 +0000 Subject: [PATCH 3/4] cred: delete task_euid() task_euid() is a very weird operation. You can see how weird it is by grepping for task_euid() - binder is its only user. task_euid() obtains the objective effective UID - it looks at the credentials of the task for purposes of acting on it as an object, but then accesses the effective UID (which the credentials.7 man page describes as "[...] used by the kernel to determine the permissions that the process will have when accessing shared resources [...]"). Since usage in Binder has now been removed, get rid of the resulting dead code. Changes to the zh_CN translation was carried out with the help of Gemini and Google Translate, and since adjusted as per Alex Shi's feedback. Suggested-by: Jann Horn Reviewed-by: Gary Guo Signed-off-by: Alice Ryhl Signed-off-by: Paul Moore --- Documentation/security/credentials.rst | 6 ++---- .../translations/zh_CN/security/credentials.rst | 4 +--- include/linux/cred.h | 1 - rust/helpers/task.c | 5 ----- rust/kernel/task.rs | 10 ---------- 5 files changed, 3 insertions(+), 23 deletions(-) diff --git a/Documentation/security/credentials.rst b/Documentation/security/credentials.rst index 4996838491b1..a39a2a2f67aa 100644 --- a/Documentation/security/credentials.rst +++ b/Documentation/security/credentials.rst @@ -393,16 +393,14 @@ the credentials so obtained when they're finished with. The result of ``__task_cred()`` should not be passed directly to ``get_cred()`` as this may race with ``commit_cred()``. -There are a couple of convenience functions to access bits of another task's -credentials, hiding the RCU magic from the caller:: +There is a convenience function to access bits of another task's credentials, +hiding the RCU magic from the caller:: uid_t task_uid(task) Task's real UID - uid_t task_euid(task) Task's effective UID If the caller is holding the RCU read lock at the time anyway, then:: __task_cred(task)->uid - __task_cred(task)->euid should be used instead. Similarly, if multiple aspects of a task's credentials need to be accessed, RCU read lock should be used, ``__task_cred()`` called, diff --git a/Documentation/translations/zh_CN/security/credentials.rst b/Documentation/translations/zh_CN/security/credentials.rst index 88fcd9152ffe..20c8696f8198 100644 --- a/Documentation/translations/zh_CN/security/credentials.rst +++ b/Documentation/translations/zh_CN/security/credentials.rst @@ -337,15 +337,13 @@ const指针上操作,因此不需要进行类型转换,但需要临时放弃 ``__task_cred()`` 的结果不应直接传递给 ``get_cred()`` , 因为这可能与 ``commit_cred()`` 发生竞争条件。 -还有一些方便的函数可以访问另一个任务凭据的特定部分,将RCU操作对调用方隐藏起来:: +有一个方便的函数可用于访问另一个任务凭据的特定部分,从而对调用方隐藏RCU机制:: uid_t task_uid(task) Task's real UID - uid_t task_euid(task) Task's effective UID 如果调用方在此时已经持有RCU读锁,则应使用:: __task_cred(task)->uid - __task_cred(task)->euid 类似地,如果需要访问任务凭据的多个方面,应使用RCU读锁,调用 ``__task_cred()`` 函数,将结果存储在临时指针中,然后从临时指针中调用凭据的各个方面,最后释放锁。 diff --git a/include/linux/cred.h b/include/linux/cred.h index c6676265a985..6ef1750c93e2 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h @@ -371,7 +371,6 @@ DEFINE_FREE(put_cred, struct cred *, if (!IS_ERR_OR_NULL(_T)) put_cred(_T)) }) #define task_uid(task) (task_cred_xxx((task), uid)) -#define task_euid(task) (task_cred_xxx((task), euid)) #define task_ucounts(task) (task_cred_xxx((task), ucounts)) #define current_cred_xxx(xxx) \ diff --git a/rust/helpers/task.c b/rust/helpers/task.c index c0e1a06ede78..b46b1433a67e 100644 --- a/rust/helpers/task.c +++ b/rust/helpers/task.c @@ -28,11 +28,6 @@ __rust_helper kuid_t rust_helper_task_uid(struct task_struct *task) return task_uid(task); } -__rust_helper kuid_t rust_helper_task_euid(struct task_struct *task) -{ - return task_euid(task); -} - #ifndef CONFIG_USER_NS __rust_helper uid_t rust_helper_from_kuid(struct user_namespace *to, kuid_t uid) { diff --git a/rust/kernel/task.rs b/rust/kernel/task.rs index eabd65bfde12..c2b3457b700c 100644 --- a/rust/kernel/task.rs +++ b/rust/kernel/task.rs @@ -217,16 +217,6 @@ pub fn uid(&self) -> Kuid { Kuid::from_raw(unsafe { bindings::task_uid(self.as_ptr()) }) } - /// Returns the objective effective UID of the given task. - /// - /// You should probably not be using this; the effective UID is normally - /// only relevant in subjective credentials. - #[inline] - pub fn euid(&self) -> Kuid { - // SAFETY: It's always safe to call `task_euid` on a valid task. - Kuid::from_raw(unsafe { bindings::task_euid(self.as_ptr()) }) - } - /// Determines whether the given task has pending signals. #[inline] pub fn signal_pending(&self) -> bool { From 0cee720cfd51402cfcb14d96cb326a36c13b823a Mon Sep 17 00:00:00 2001 From: Wang Yan Date: Fri, 3 Jul 2026 20:09:51 +0800 Subject: [PATCH 4/4] selftests/lsm: Fix memory leak in attr_lsm_count The calloc-allocated buffer in attr_lsm_count() is never released on any exit path, including both the normal return path and the early return when read_sysfs_lsms fails, resulting in a heap memory leak. Add free() for the buffer on all return branches to fix the leak. Fixes: d3d929a8b0cd ("LSM: selftests for Linux Security Module syscalls") Signed-off-by: Wang Yan Reviewed-by: William Roberts Tested-by: William Roberts Signed-off-by: Paul Moore --- tools/testing/selftests/lsm/common.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/lsm/common.c b/tools/testing/selftests/lsm/common.c index 9ad258912646..927dce4f04cb 100644 --- a/tools/testing/selftests/lsm/common.c +++ b/tools/testing/selftests/lsm/common.c @@ -76,7 +76,7 @@ int attr_lsm_count(void) return 0; if (read_sysfs_lsms(names, sysconf(_SC_PAGESIZE))) - return 0; + goto out; if (strstr(names, "selinux")) count++; @@ -85,5 +85,7 @@ int attr_lsm_count(void) if (strstr(names, "apparmor")) count++; +out: + free(names); return count; }