aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavidlohr Bueso <[email protected]>2021-12-10 10:20:58 -0800
committerJens Axboe <[email protected]>2021-12-10 11:26:07 -0700
commite6a59aac8a8713f335a37d762db0dbe80e7f6d38 (patch)
tree5dbbaa64f3b99f6340475b25b58e0cd0d27b70b1
parenta5c24552354ff1e35bb4022ebc0b791eb7882b04 (diff)
block: fix ioprio_get(IOPRIO_WHO_PGRP) vs setuid(2)
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 <[email protected]> Signed-off-by: Davidlohr Bueso <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
-rw-r--r--block/ioprio.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/block/ioprio.c b/block/ioprio.c
index 313c14a70bbd..6f01d35a5145 100644
--- a/block/ioprio.c
+++ b/block/ioprio.c
@@ -220,6 +220,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)
@@ -229,6 +230,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);