From: Greg Kroah-Hartman Date: Tue, 22 Aug 2017 17:48:46 +0000 (-0700) Subject: 4.12-stable patches X-Git-Tag: v3.18.67~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b26225d6e302bb71a0b3bd8b798a996148864a29;p=thirdparty%2Fkernel%2Fstable-queue.git 4.12-stable patches added patches: pids-make-task_tgid_nr_ns-safe.patch --- diff --git a/queue-4.12/pids-make-task_tgid_nr_ns-safe.patch b/queue-4.12/pids-make-task_tgid_nr_ns-safe.patch new file mode 100644 index 00000000000..5d3adb63686 --- /dev/null +++ b/queue-4.12/pids-make-task_tgid_nr_ns-safe.patch @@ -0,0 +1,146 @@ +From dd1c1f2f2028a7b851f701fc6a8ebe39dcb95e7c Mon Sep 17 00:00:00 2001 +From: Oleg Nesterov +Date: Mon, 21 Aug 2017 17:35:02 +0200 +Subject: pids: make task_tgid_nr_ns() safe + +From: Oleg Nesterov + +commit dd1c1f2f2028a7b851f701fc6a8ebe39dcb95e7c upstream. + +This was reported many times, and this was even mentioned in commit +52ee2dfdd4f5 ("pids: refactor vnr/nr_ns helpers to make them safe") but +somehow nobody bothered to fix the obvious problem: task_tgid_nr_ns() is +not safe because task->group_leader points to nowhere after the exiting +task passes exit_notify(), rcu_read_lock() can not help. + +We really need to change __unhash_process() to nullify group_leader, +parent, and real_parent, but this needs some cleanups. Until then we +can turn task_tgid_nr_ns() into another user of __task_pid_nr_ns() and +fix the problem. + +Reported-by: Troy Kensinger +Signed-off-by: Oleg Nesterov +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/pid.h | 4 ++- + include/linux/sched.h | 51 ++++++++++++++++++++++++++------------------------ + kernel/pid.c | 11 +++------- + 3 files changed, 34 insertions(+), 32 deletions(-) + +--- a/include/linux/pid.h ++++ b/include/linux/pid.h +@@ -8,7 +8,9 @@ enum pid_type + PIDTYPE_PID, + PIDTYPE_PGID, + PIDTYPE_SID, +- PIDTYPE_MAX ++ PIDTYPE_MAX, ++ /* only valid to __task_pid_nr_ns() */ ++ __PIDTYPE_TGID + }; + + /* +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -1132,13 +1132,6 @@ static inline pid_t task_tgid_nr(struct + return tsk->tgid; + } + +-extern pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); +- +-static inline pid_t task_tgid_vnr(struct task_struct *tsk) +-{ +- return pid_vnr(task_tgid(tsk)); +-} +- + /** + * pid_alive - check that a task structure is not stale + * @p: Task structure to be checked. +@@ -1154,23 +1147,6 @@ static inline int pid_alive(const struct + return p->pids[PIDTYPE_PID].pid != NULL; + } + +-static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns) +-{ +- pid_t pid = 0; +- +- rcu_read_lock(); +- if (pid_alive(tsk)) +- pid = task_tgid_nr_ns(rcu_dereference(tsk->real_parent), ns); +- rcu_read_unlock(); +- +- return pid; +-} +- +-static inline pid_t task_ppid_nr(const struct task_struct *tsk) +-{ +- return task_ppid_nr_ns(tsk, &init_pid_ns); +-} +- + static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) + { + return __task_pid_nr_ns(tsk, PIDTYPE_PGID, ns); +@@ -1192,6 +1168,33 @@ static inline pid_t task_session_vnr(str + return __task_pid_nr_ns(tsk, PIDTYPE_SID, NULL); + } + ++static inline pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) ++{ ++ return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, ns); ++} ++ ++static inline pid_t task_tgid_vnr(struct task_struct *tsk) ++{ ++ return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, NULL); ++} ++ ++static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns) ++{ ++ pid_t pid = 0; ++ ++ rcu_read_lock(); ++ if (pid_alive(tsk)) ++ pid = task_tgid_nr_ns(rcu_dereference(tsk->real_parent), ns); ++ rcu_read_unlock(); ++ ++ return pid; ++} ++ ++static inline pid_t task_ppid_nr(const struct task_struct *tsk) ++{ ++ return task_ppid_nr_ns(tsk, &init_pid_ns); ++} ++ + /* Obsolete, do not use: */ + static inline pid_t task_pgrp_nr(struct task_struct *tsk) + { +--- a/kernel/pid.c ++++ b/kernel/pid.c +@@ -527,8 +527,11 @@ pid_t __task_pid_nr_ns(struct task_struc + if (!ns) + ns = task_active_pid_ns(current); + if (likely(pid_alive(task))) { +- if (type != PIDTYPE_PID) ++ if (type != PIDTYPE_PID) { ++ if (type == __PIDTYPE_TGID) ++ type = PIDTYPE_PID; + task = task->group_leader; ++ } + nr = pid_nr_ns(rcu_dereference(task->pids[type].pid), ns); + } + rcu_read_unlock(); +@@ -537,12 +540,6 @@ pid_t __task_pid_nr_ns(struct task_struc + } + EXPORT_SYMBOL(__task_pid_nr_ns); + +-pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) +-{ +- return pid_nr_ns(task_tgid(tsk), ns); +-} +-EXPORT_SYMBOL(task_tgid_nr_ns); +- + struct pid_namespace *task_active_pid_ns(struct task_struct *tsk) + { + return ns_of_pid(task_pid(tsk)); diff --git a/queue-4.12/series b/queue-4.12/series index de0373519d0..ac12d09f174 100644 --- a/queue-4.12/series +++ b/queue-4.12/series @@ -35,3 +35,4 @@ genirq-restore-trigger-settings-in-irq_modify_status.patch genirq-ipi-fixup-checks-against-nr_cpu_ids.patch kernel-watchdog-prevent-false-positives-with-turbo-modes.patch sanitize-move_pages-permission-checks.patch +pids-make-task_tgid_nr_ns-safe.patch