]> git.baikalelectronics.ru Git - kernel.git/commit
kernel/sys.c: only take tasklist_lock for get/setpriority(PRIO_PGRP)
authorDavidlohr Bueso <dave@stgolabs.net>
Thu, 20 Jan 2022 02:08:47 +0000 (18:08 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 20 Jan 2022 06:52:53 +0000 (08:52 +0200)
commit57d12d123e919a10cbf78209d648c69dbc478f5a
treeeda50630e7cdc86439aafa06d88bf3ad8cf6d447
parent837fa5c2c9a2ce25ad577bb13b5fdb726fc3b7f1
kernel/sys.c: only take tasklist_lock for get/setpriority(PRIO_PGRP)

PRIO_PGRP needs the tasklist_lock mainly to serialize vs setpgid(2), to
protect against any concurrent change_pid(PIDTYPE_PGID) that can move
the task from one hlist to another while iterating.

However, the remaining can only rely only on RCU:

PRIO_PROCESS only does the task lookup and never iterates over tasklist
and we already have an rcu-aware stable pointer.

PRIO_USER is already racy vs setuid(2) so with creds being rcu
protected, we can end up seeing stale data.  When removing the
tasklist_lock there can be a race with (i) fork but this is benign as
the child's nice is inherited and the new task is not observable by the
user yet either, hence the return semantics do not differ.  And (ii) a
race with exit, which is a small window and can cause us to miss a task
which was removed from the list and it had the highest nice.

Similarly change the buggy do_each_thread/while_each_thread combo in
PRIO_USER for the rcu-safe for_each_process_thread flavor, which doesn't
make use of next_thread/p->thread_group.

[akpm@linux-foundation.org: coding style fixes]

Link: https://lkml.kernel.org/r/20211210182250.43734-1-dave@stgolabs.net
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
kernel/sys.c