From 8feebc6713cd78cbba8c4e2a6d92299669052026 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Mon, 27 Apr 2020 14:32:54 -0500 Subject: posix-cpu-timer: Tidy up group_leader logic in lookup_task Replace has_group_leader_pid with thread_group_leader. Years ago Oleg suggested changing thread_group_leader to has_group_leader_pid to handle races. Looking at the code then and now I don't see how it ever helped. Especially as then the code really did need to be the thread_group_leader. Today it doesn't make a difference if thread_group_leader races with de_thread as the task returned from lookup_task in the non-thread case is just used to find values in task->signal. Since the races with de_thread have never been handled revert has_group_header_pid to thread_group_leader for clarity. Update the comment in lookup_task to remove implementation details that are no longer true and to mention task->signal instead of task->sighand, as the relevant cpu timer details are all in task->signal. Ref: 55e8c8eb2c7b ("posix-cpu-timers: Store a reference to a pid not a task") Ref: c0deae8c9587 ("posix-cpu-timers: Rcu_read_lock/unlock protect find_task_by_vpid call") Signed-off-by: "Eric W. Biederman" --- kernel/time/posix-cpu-timers.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index 2fd3b3fa68bf..e4051e417bcb 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -69,12 +69,8 @@ static struct task_struct *lookup_task(const pid_t pid, bool thread, if (gettime) { /* * For clock_gettime(PROCESS) the task does not need to be - * the actual group leader. tsk->sighand gives + * the actual group leader. task->signal gives * access to the group's clock. - * - * Timers need the group leader because they take a - * reference on it and store the task pointer until the - * timer is destroyed. */ return (p == current || thread_group_leader(p)) ? p : NULL; } @@ -82,7 +78,7 @@ static struct task_struct *lookup_task(const pid_t pid, bool thread, /* * For processes require that p is group leader. */ - return has_group_leader_pid(p) ? p : NULL; + return thread_group_leader(p) ? p : NULL; } static struct task_struct *__get_task_for_clock(const clockid_t clock, -- cgit v1.2.3 From c7f5194054e103d18d267385b866b5b90511a425 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 28 Apr 2020 13:00:39 -0500 Subject: posix-cpu-timer: Unify the now redundant code in lookup_task Now that both !thread paths through lookup_task call thread_group_leader, unify them into the single test at the end of lookup_task. This unification just makes it clear what is happening in the gettime special case of lookup_task. Signed-off-by: "Eric W. Biederman" --- kernel/time/posix-cpu-timers.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index e4051e417bcb..b7f972fb115e 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -66,14 +66,13 @@ static struct task_struct *lookup_task(const pid_t pid, bool thread, if (thread) return same_thread_group(p, current) ? p : NULL; - if (gettime) { - /* - * For clock_gettime(PROCESS) the task does not need to be - * the actual group leader. task->signal gives - * access to the group's clock. - */ - return (p == current || thread_group_leader(p)) ? p : NULL; - } + /* + * For clock_gettime(PROCESS) the task does not need to be + * the actual group leader. task->signal gives + * access to the group's clock. + */ + if (gettime && (p == current)) + return p; /* * For processes require that p is group leader. -- cgit v1.2.3 From 610b818856e1477964b59040c740f6ec55883045 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sun, 26 Apr 2020 07:51:03 -0500 Subject: exec: Remove BUG_ON(has_group_leader_pid) With the introduction of exchange_tids thread_group_leader and has_group_leader_pid have become equivalent. Further at this point in the code a thread group has exactly two threads, the previous thread_group_leader that is waiting to be reaped and tsk. So we know it is impossible for tsk to be the thread_group_leader. This is also the last user of has_group_leader_pid so removing this check will allow has_group_leader_pid to be removed. So remove the "BUG_ON(has_group_leader_pid)" that will never fire. Signed-off-by: "Eric W. Biederman" --- fs/exec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/exec.c b/fs/exec.c index 9b60f927afd7..6ab1c19d84fa 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1176,7 +1176,6 @@ static int de_thread(struct task_struct *tsk) tsk->start_boottime = leader->start_boottime; BUG_ON(!same_thread_group(leader, tsk)); - BUG_ON(has_group_leader_pid(tsk)); /* * An exec() starts a new thread group with the * TGID of the previous thread group. Rehash the -- cgit v1.2.3 From bbd40fc4816d5329a89397206ece9f1763787a88 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sun, 26 Apr 2020 07:59:55 -0500 Subject: signal: Remove has_group_leader_pid After the introduction of exchange_tids has_group_leader_pid is equivalent to thread_group_leader. After the last couple of cleanups has_group_leader_pid has no more callers. So remove the now unused and redundant has_group_leader_pid. Signed-off-by: "Eric W. Biederman" --- include/linux/sched/signal.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index 3e5b090c16d4..0ee5e696c5d8 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -654,17 +654,6 @@ static inline bool thread_group_leader(struct task_struct *p) return p->exit_signal >= 0; } -/* Do to the insanities of de_thread it is possible for a process - * to have the pid of the thread group leader without actually being - * the thread group leader. For iteration through the pids in proc - * all we care about is that we have a task with the appropriate - * pid, we don't actually care if we have the right task. - */ -static inline bool has_group_leader_pid(struct task_struct *p) -{ - return task_pid(p) == task_tgid(p); -} - static inline bool same_thread_group(struct task_struct *p1, struct task_struct *p2) { -- cgit v1.2.3