diff options
author | Davidlohr Bueso <dave@stgolabs.net> | 2021-12-10 21:20:58 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-12-14 12:18:07 +0300 |
commit | 23047a238f44bd11c0316598691eef2bfd2d557e (patch) | |
tree | f59f33e563d516485a46bec24181dbf074580041 /block/ioprio.c | |
parent | 1e06540f8d2b94d0459e6cd2724001e5c8657416 (diff) | |
download | linux-23047a238f44bd11c0316598691eef2bfd2d557e.tar.xz |
block: fix ioprio_get(IOPRIO_WHO_PGRP) vs setuid(2)
commit e6a59aac8a8713f335a37d762db0dbe80e7f6d38 upstream.
do_each_pid_thread(PIDTYPE_PGID) can race with a concurrent
change_pid(PIDTYPE_PGID) that can move the task from one hlist
to another while iterating. Serialize ioprio_get to take
the tasklist_lock in this case, just like it's set counterpart.
Fixes: d69b78ba1de (ioprio: grab rcu_read_lock in sys_ioprio_{set,get}())
Acked-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Link: https://lore.kernel.org/r/20211210182058.43417-1-dave@stgolabs.net
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'block/ioprio.c')
-rw-r--r-- | block/ioprio.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/block/ioprio.c b/block/ioprio.c index f9821080c92c..f0ee9cc33d17 100644 --- a/block/ioprio.c +++ b/block/ioprio.c @@ -206,6 +206,7 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who) pgrp = task_pgrp(current); else pgrp = find_vpid(who); + read_lock(&tasklist_lock); do_each_pid_thread(pgrp, PIDTYPE_PGID, p) { tmpio = get_task_ioprio(p); if (tmpio < 0) @@ -215,6 +216,8 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who) else ret = ioprio_best(ret, tmpio); } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); + read_unlock(&tasklist_lock); + break; case IOPRIO_WHO_USER: uid = make_kuid(current_user_ns(), who); |