diff options
author | Ben Segall <bsegall@google.com> | 2015-11-06 19:32:48 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-06 20:50:42 -0500 |
commit | 8639b46139b0e4ea3b1ab1c274e410ee327f1d89 (patch) | |
tree | ef62c65fa87b03133678a76aba7a6e50a24a2c0d | |
parent | de90a6bcaede81f35e8caf4566d1006267230377 (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.c | 6 | ||||
-rw-r--r-- | kernel/sys.c | 4 |
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; |