summaryrefslogtreecommitdiff
path: root/kernel/reboot.c
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2026-07-20 13:13:43 +0200
committerJoel Granados <joel.granados@kernel.org>2026-08-05 15:28:23 +0200
commit7170ca01623b399c97f2ae9d3e228badc1f25ea3 (patch)
tree48b8215e0e2833c9cd8259903fafa6bef97f9142 /kernel/reboot.c
parent4280dd6da352c0544672102de09df15eb326a145 (diff)
sysctl: move the "cad_pid" entry from pid_table[] to kern_reboot_table[]
cad_pid is global, and kill_cad_pid() is only used in the root namespace. However, due to pid_table_root_permissions(), a non-root user can unshare pid/user namespaces and modify it from the child namespace. This makes no sense and is simply wrong. Move it to kern_reboot_table[] where it logically belongs; this ensures that only GLOBAL_ROOT_UID can read/modify this sysctl. Note that this patch doesn't preserve "#ifdef CONFIG_PROC_SYSCTL" around the "cad_pid"; CONFIG_PROC_SYSCTL selects CONFIG_SYSCTL, so it is always set when kern_reboot_table[] is compiled. Cc: stable@vger.kernel.org Fixes: e054bcbe7e7a ("sysctl: move cad_pid into kernel/pid.c") Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Alexey Gladkov <legion@kernel.org> Reviewed-by: Bradley Morgan <include@grrlz.net> Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com> Signed-off-by: Joel Granados <joel.granados@kernel.org>
Diffstat (limited to 'kernel/reboot.c')
-rw-r--r--kernel/reboot.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/kernel/reboot.c b/kernel/reboot.c
index 695c33e75efd..f070c5c1103a 100644
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -1366,6 +1366,29 @@ static struct attribute *reboot_attrs[] = {
};
#ifdef CONFIG_SYSCTL
+static int proc_do_cad_pid(const struct ctl_table *table, int write, void *buffer,
+ size_t *lenp, loff_t *ppos)
+{
+ struct ctl_table tmp_table = *table;
+ struct pid *new_pid;
+ pid_t tmp_pid;
+ int r;
+
+ tmp_pid = pid_vnr(cad_pid);
+ tmp_table.data = &tmp_pid;
+
+ r = proc_dointvec(&tmp_table, write, buffer, lenp, ppos);
+ if (r || !write)
+ return r;
+
+ new_pid = find_get_pid(tmp_pid);
+ if (!new_pid)
+ return -ESRCH;
+
+ put_pid(xchg(&cad_pid, new_pid));
+ return 0;
+}
+
static const struct ctl_table kern_reboot_table[] = {
{
.procname = "poweroff_cmd",
@@ -1381,6 +1404,12 @@ static const struct ctl_table kern_reboot_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec,
},
+ {
+ .procname = "cad_pid",
+ .maxlen = sizeof(int),
+ .mode = 0600,
+ .proc_handler = proc_do_cad_pid,
+ },
};
static void __init kernel_reboot_sysctls_init(void)