From 713041d0d51b6405dfcfdf7650f7309421e512db Mon Sep 17 00:00:00 2001 From: luojiajun Date: Mon, 15 Apr 2019 21:33:12 +0800 Subject: [PATCH] some fixes for pid_ns-Make-pid_max-per-namespace euler inclusion category: bugfix bugzilla: NA CVE: NA ------------------------------------------------- we find some bugs in pid_ns-Make-pid_max-per-namespace 1.In alloc pid, the current pid namespace's pid_max is used for trying to allocate pids from the current pid namespace to the parent pid namespaces until the root pid namespace is reached. it's not correct. so using tmp->pid_max instead of task_active_pid_ns(current)->pid_max. 2.In pid_ns_ctl_handler, init_pid_ns.pid_max is always used but the value of ns_last_pid is already per-pid-namespace, so extra2 field needs to be overridden by per-pid-namespace's pid_max 3.In proc_dointvec_pidmax, We can use task_active_pid_ns(current)->pid_max here. It's much shorter and descriptive. 4.In __init pid_idr_init, kmemleak_not_leak is not be used, it will cause memleak alarm but memory is actually not leak. v1->v2: fix some format problems v2->v3: use pid_ns instead of task_active_pid_ns(current) in pid_ns_ctl_handler Signed-off-by: luojiajun Reviewed-by: Hou Tao Signed-off-by: Yang Yingliang --- kernel/pid.c | 9 ++++++--- kernel/pid_namespace.c | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/kernel/pid.c b/kernel/pid.c index 5dc0d3fc5efe..d4df9c3387e1 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -40,6 +40,7 @@ #include #include #include +#include struct pid init_struct_pid = { .count = ATOMIC_INIT(1), @@ -189,7 +190,7 @@ struct pid *alloc_pid(struct pid_namespace *ns) * a partially initialized PID (see below). */ nr = idr_alloc_cyclic(&tmp->idr, NULL, pid_min, - task_active_pid_ns(current)->pid_max, + tmp->pid_max, GFP_ATOMIC); spin_unlock_irq(&pidmap_lock); idr_preload_end(); @@ -457,7 +458,7 @@ static int proc_dointvec_pidmax(struct ctl_table *table, int write, struct ctl_table tmp; tmp = *table; - tmp.data = ¤t->nsproxy->pid_ns_for_children->pid_max; + tmp.data = &task_active_pid_ns(current)->pid_max; return proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); } @@ -479,6 +480,7 @@ static struct ctl_path pid_kern_path[] = { { .procname = "kernel" }, {} }; void __init pid_idr_init(void) { + struct ctl_table_header *hdr; int pid_max = init_pid_ns.pid_max; /* Verify no one has done anything silly: */ @@ -498,5 +500,6 @@ void __init pid_idr_init(void) init_pid_ns.pid_cachep = KMEM_CACHE(pid, SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT); - register_sysctl_paths(pid_kern_path, pid_ctl_table); + hdr = register_sysctl_paths(pid_kern_path, pid_ctl_table); + kmemleak_not_leak(hdr); } diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 80d39dc961d7..d009d98e3fe2 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -283,6 +283,8 @@ static int pid_ns_ctl_handler(struct ctl_table *table, int write, next = idr_get_cursor(&pid_ns->idr) - 1; tmp.data = &next; + tmp.extra2 = &pid_ns->pid_max; + ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); if (!ret && write) idr_set_cursor(&pid_ns->idr, next + 1); -- GitLab