diff options
author | Oleg Nesterov <oleg@redhat.com> | 2017-08-21 11:35:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-08-21 15:47:31 -0400 |
commit | dd1c1f2f2028a7b851f701fc6a8ebe39dcb95e7c (patch) | |
tree | 96b5e5466504cc8c88b0f0435e80f70f0c627c58 /include/linux/sched.h | |
parent | 14ccee78fc82f5512908f4424f541549a5705b89 (diff) |
pids: make task_tgid_nr_ns() safe
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 <tkensinger@google.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/sched.h')
-rw-r--r-- | include/linux/sched.h | 51 |
1 files changed, 27 insertions, 24 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index 8337e2db0bb2..c05ac5f5aa03 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1163,13 +1163,6 @@ static inline pid_t task_tgid_nr(struct task_struct *tsk) | |||
1163 | return tsk->tgid; | 1163 | return tsk->tgid; |
1164 | } | 1164 | } |
1165 | 1165 | ||
1166 | extern pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); | ||
1167 | |||
1168 | static inline pid_t task_tgid_vnr(struct task_struct *tsk) | ||
1169 | { | ||
1170 | return pid_vnr(task_tgid(tsk)); | ||
1171 | } | ||
1172 | |||
1173 | /** | 1166 | /** |
1174 | * pid_alive - check that a task structure is not stale | 1167 | * pid_alive - check that a task structure is not stale |
1175 | * @p: Task structure to be checked. | 1168 | * @p: Task structure to be checked. |
@@ -1185,23 +1178,6 @@ static inline int pid_alive(const struct task_struct *p) | |||
1185 | return p->pids[PIDTYPE_PID].pid != NULL; | 1178 | return p->pids[PIDTYPE_PID].pid != NULL; |
1186 | } | 1179 | } |
1187 | 1180 | ||
1188 | static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns) | ||
1189 | { | ||
1190 | pid_t pid = 0; | ||
1191 | |||
1192 | rcu_read_lock(); | ||
1193 | if (pid_alive(tsk)) | ||
1194 | pid = task_tgid_nr_ns(rcu_dereference(tsk->real_parent), ns); | ||
1195 | rcu_read_unlock(); | ||
1196 | |||
1197 | return pid; | ||
1198 | } | ||
1199 | |||
1200 | static inline pid_t task_ppid_nr(const struct task_struct *tsk) | ||
1201 | { | ||
1202 | return task_ppid_nr_ns(tsk, &init_pid_ns); | ||
1203 | } | ||
1204 | |||
1205 | static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) | 1181 | static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) |
1206 | { | 1182 | { |
1207 | return __task_pid_nr_ns(tsk, PIDTYPE_PGID, ns); | 1183 | return __task_pid_nr_ns(tsk, PIDTYPE_PGID, ns); |
@@ -1223,6 +1199,33 @@ static inline pid_t task_session_vnr(struct task_struct *tsk) | |||
1223 | return __task_pid_nr_ns(tsk, PIDTYPE_SID, NULL); | 1199 | return __task_pid_nr_ns(tsk, PIDTYPE_SID, NULL); |
1224 | } | 1200 | } |
1225 | 1201 | ||
1202 | static inline pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) | ||
1203 | { | ||
1204 | return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, ns); | ||
1205 | } | ||
1206 | |||
1207 | static inline pid_t task_tgid_vnr(struct task_struct *tsk) | ||
1208 | { | ||
1209 | return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, NULL); | ||
1210 | } | ||
1211 | |||
1212 | static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns) | ||
1213 | { | ||
1214 | pid_t pid = 0; | ||
1215 | |||
1216 | rcu_read_lock(); | ||
1217 | if (pid_alive(tsk)) | ||
1218 | pid = task_tgid_nr_ns(rcu_dereference(tsk->real_parent), ns); | ||
1219 | rcu_read_unlock(); | ||
1220 | |||
1221 | return pid; | ||
1222 | } | ||
1223 | |||
1224 | static inline pid_t task_ppid_nr(const struct task_struct *tsk) | ||
1225 | { | ||
1226 | return task_ppid_nr_ns(tsk, &init_pid_ns); | ||
1227 | } | ||
1228 | |||
1226 | /* Obsolete, do not use: */ | 1229 | /* Obsolete, do not use: */ |
1227 | static inline pid_t task_pgrp_nr(struct task_struct *tsk) | 1230 | static inline pid_t task_pgrp_nr(struct task_struct *tsk) |
1228 | { | 1231 | { |