Commit 8639b461 authored by Ben Segall's avatar Ben Segall Committed by Linus Torvalds

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: default avatarBen 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: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent de90a6bc
...@@ -123,7 +123,8 @@ SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio) ...@@ -123,7 +123,8 @@ SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio)
break; break;
do_each_thread(g, p) { do_each_thread(g, p) {
if (!uid_eq(task_uid(p), uid)) if (!uid_eq(task_uid(p), uid) ||
!task_pid_vnr(p))
continue; continue;
ret = set_task_ioprio(p, ioprio); ret = set_task_ioprio(p, ioprio);
if (ret) if (ret)
...@@ -220,7 +221,8 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who) ...@@ -220,7 +221,8 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who)
break; break;
do_each_thread(g, p) { do_each_thread(g, p) {
if (!uid_eq(task_uid(p), user->uid)) if (!uid_eq(task_uid(p), user->uid) ||
!task_pid_vnr(p))
continue; continue;
tmpio = get_task_ioprio(p); tmpio = get_task_ioprio(p);
if (tmpio < 0) if (tmpio < 0)
......
...@@ -222,7 +222,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval) ...@@ -222,7 +222,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)
goto out_unlock; /* No processes for this user */ goto out_unlock; /* No processes for this user */
} }
do_each_thread(g, p) { do_each_thread(g, p) {
if (uid_eq(task_uid(p), uid)) if (uid_eq(task_uid(p), uid) && task_pid_vnr(p))
error = set_one_prio(p, niceval, error); error = set_one_prio(p, niceval, error);
} while_each_thread(g, p); } while_each_thread(g, p);
if (!uid_eq(uid, cred->uid)) if (!uid_eq(uid, cred->uid))
...@@ -290,7 +290,7 @@ SYSCALL_DEFINE2(getpriority, int, which, int, who) ...@@ -290,7 +290,7 @@ SYSCALL_DEFINE2(getpriority, int, which, int, who)
goto out_unlock; /* No processes for this user */ goto out_unlock; /* No processes for this user */
} }
do_each_thread(g, p) { do_each_thread(g, p) {
if (uid_eq(task_uid(p), uid)) { if (uid_eq(task_uid(p), uid) && task_pid_vnr(p)) {
niceval = nice_to_rlimit(task_nice(p)); niceval = nice_to_rlimit(task_nice(p));
if (niceval > retval) if (niceval > retval)
retval = niceval; retval = niceval;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment