]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bpf: task_group_seq_get_next: use __next_thread() rather than next_thread()
authorOleg Nesterov <oleg@redhat.com>
Tue, 14 Nov 2023 16:32:34 +0000 (17:32 +0100)
committerAlexei Starovoitov <ast@kernel.org>
Sun, 19 Nov 2023 19:43:44 +0000 (11:43 -0800)
Lockless use of next_thread() should be avoided, kernel/bpf/task_iter.c
is the last user and the usage is wrong.

task_group_seq_get_next() can return the group leader twice if it races
with mt-thread exec which changes the group->leader's pid.

Change the main loop to use __next_thread(), kill "next_tid == common->pid"
check.

__next_thread() can't loop forever, we can also change this code to retry
if next_tid == 0.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Yonghong Song <yonghong.song@linux.dev>
Link: https://lore.kernel.org/r/20231114163234.GA890@redhat.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/task_iter.c

index 26082b97894d3c0d64f4c909122ec3820f73f197..51ae15e2b2902fae44233de71bcaa7b2fa517a89 100644 (file)
@@ -70,15 +70,13 @@ static struct task_struct *task_group_seq_get_next(struct bpf_iter_seq_task_comm
                return NULL;
 
 retry:
-       task = next_thread(task);
+       task = __next_thread(task);
+       if (!task)
+               return NULL;
 
        next_tid = __task_pid_nr_ns(task, PIDTYPE_PID, common->ns);
-       if (!next_tid || next_tid == common->pid) {
-               /* Run out of tasks of a process.  The tasks of a
-                * thread_group are linked as circular linked list.
-                */
-               return NULL;
-       }
+       if (!next_tid)
+               goto retry;
 
        if (skip_if_dup_files && task->files == task->group_leader->files)
                goto retry;