aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Segall <bsegall@google.com>2015-11-06 19:32:48 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-06 20:50:42 -0500
commit8639b46139b0e4ea3b1ab1c274e410ee327f1d89 (patch)
treeef62c65fa87b03133678a76aba7a6e50a24a2c0d
parentde90a6bcaede81f35e8caf4566d1006267230377 (diff)
pidns: fix set/getpriority and ioprio_set/get in PRIO_USER mode
setpriority(PRIO_USER, 0, x) will change the priority of tasks outside of the current pid namespace. This is in contrast to both the other modes of setpriority and the example of kill(-1). Fix this. getpriority and ioprio have the same failure mode, fix them too. Eric said: : After some more thinking about it this patch sounds justifiable. : : My goal with namespaces is not to build perfect isolation mechanisms : as that can get into ill defined territory, but to build well defined : mechanisms. And to handle the corner cases so you can use only : a single namespace with well defined results. : : In this case you have found the two interfaces I am aware of that : identify processes by uid instead of by pid. Which quite frankly is : weird. Unfortunately the weird unexpected cases are hard to handle : in the usual way. : : I was hoping for a little more information. Changes like this one we : have to be careful of because someone might be depending on the current : behavior. I don't think they are and I do think this make sense as part : of the pid namespace. Signed-off-by: Ben Segall <bsegall@google.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Ambrose Feinstein <ambrose@google.com> Acked-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--block/ioprio.c6
-rw-r--r--kernel/sys.c4
2 files changed, 6 insertions, 4 deletions
diff --git a/block/ioprio.c b/block/ioprio.c
index 31666c92b46a..cc7800e9eb44 100644
--- a/block/ioprio.c
+++ b/block/ioprio.c
@@ -123,7 +123,8 @@ SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio)
123 break; 123 break;
124 124
125 do_each_thread(g, p) { 125 do_each_thread(g, p) {
126 if (!uid_eq(task_uid(p), uid)) 126 if (!uid_eq(task_uid(p), uid) ||
127 !task_pid_vnr(p))
127 continue; 128 continue;
128 ret = set_task_ioprio(p, ioprio); 129 ret = set_task_ioprio(p, ioprio);
129 if (ret) 130 if (ret)
@@ -220,7 +221,8 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who)
220 break; 221 break;
221 222
222 do_each_thread(g, p) { 223 do_each_thread(g, p) {
223 if (!uid_eq(task_uid(p), user->uid)) 224 if (!uid_eq(task_uid(p), user->uid) ||
225 !task_pid_vnr(p))
224 continue; 226 continue;
225 tmpio = get_task_ioprio(p); 227 tmpio = get_task_ioprio(p);
226 if (tmpio < 0) 228 if (tmpio < 0)
diff --git a/kernel/sys.c b/kernel/sys.c
index fa2f2f671a5c..6af9212ab5aa 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -222,7 +222,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)
222 goto out_unlock; /* No processes for this user */ 222 goto out_unlock; /* No processes for this user */
223 } 223 }
224 do_each_thread(g, p) { 224 do_each_thread(g, p) {
225 if (uid_eq(task_uid(p), uid)) 225 if (uid_eq(task_uid(p), uid) && task_pid_vnr(p))
226 error = set_one_prio(p, niceval, error); 226 error = set_one_prio(p, niceval, error);
227 } while_each_thread(g, p); 227 } while_each_thread(g, p);
228 if (!uid_eq(uid, cred->uid)) 228 if (!uid_eq(uid, cred->uid))
@@ -290,7 +290,7 @@ SYSCALL_DEFINE2(getpriority, int, which, int, who)
290 goto out_unlock; /* No processes for this user */ 290 goto out_unlock; /* No processes for this user */
291 } 291 }
292 do_each_thread(g, p) { 292 do_each_thread(g, p) {
293 if (uid_eq(task_uid(p), uid)) { 293 if (uid_eq(task_uid(p), uid) && task_pid_vnr(p)) {
294 niceval = nice_to_rlimit(task_nice(p)); 294 niceval = nice_to_rlimit(task_nice(p));
295 if (niceval > retval) 295 if (niceval > retval)
296 retval = niceval; 296 retval = niceval;