[Devel] Re: [RFC 4/5] user namespaces: allow killing tasks in your own or child userns
Serge E. Hallyn
serge at hallyn.com
Fri Dec 31 20:45:22 PST 2010
Quoting Eric W. Biederman (ebiederm at xmission.com):
> "Serge E. Hallyn" <serge at hallyn.com> writes:
>
> > Quoting Eric W. Biederman (ebiederm at xmission.com):
> >> > --- a/kernel/signal.c
> >> > +++ b/kernel/signal.c
> >> > @@ -659,11 +686,7 @@ static int check_kill_permission(int sig, struct siginfo *info,
> >> > cred = current_cred();
> >> > tcred = __task_cred(t);
> >> Nit pick you don't need to compute cred and tcred here now.
> >
> > Just to make sure I understand right: you mean wait until after the
> > same_thread_group() check to save calculation in that case, right?
>
> I mean cred and tcred are only use in kill_ok_by_cred.
> So we can eliminate those two variables from check_kill_permission.
Thanks for the review. Here is an updated version.
Subject: [PATCH 4/5] allow killing tasks in your own or child userns
Changelog:
Dec 8: Fixed bug in my check_kill_permission pointed out by
Eric Biederman.
Dec 13: Apply Eric's suggestion to pass target task into kill_ok_by_cred()
for clarity
Dec 31: address comment by Eric Biederman:
don't need cred/tcred in check_kill_permission.
Signed-off-by: Serge E. Hallyn <serge.hallyn at canonical.com>
---
kernel/signal.c | 36 ++++++++++++++++++++++++++++--------
1 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/kernel/signal.c b/kernel/signal.c
index 4e3cff1..d890c99 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -636,13 +636,39 @@ static inline bool si_fromuser(const struct siginfo *info)
}
/*
+ * called with RCU read lock from check_kill_permission()
+ */
+static inline int kill_ok_by_cred(struct task_struct *t)
+{
+ struct cred *cred = current_cred();
+ struct cred *tcred = __task_cred(t);
+
+ if (cred->user->user_ns != tcred->user->user_ns) {
+ /* userids are not equivalent - either you have the
+ capability to the target user ns or you don't */
+ if (ns_capable(tcred->user->user_ns, CAP_KILL))
+ return 1;
+ return 0;
+ }
+
+ /* same user namespace - usual credentials checks apply */
+ if ((cred->euid ^ tcred->suid) &&
+ (cred->euid ^ tcred->uid) &&
+ (cred->uid ^ tcred->suid) &&
+ (cred->uid ^ tcred->uid) &&
+ !ns_capable(tcred->user->user_ns, CAP_KILL))
+ return 0;
+
+ return 1;
+}
+
+/*
* Bad permissions for sending the signal
* - the caller must hold the RCU read lock
*/
static int check_kill_permission(int sig, struct siginfo *info,
struct task_struct *t)
{
- const struct cred *cred, *tcred;
struct pid *sid;
int error;
@@ -656,14 +682,8 @@ static int check_kill_permission(int sig, struct siginfo *info,
if (error)
return error;
- cred = current_cred();
- tcred = __task_cred(t);
if (!same_thread_group(current, t) &&
- (cred->euid ^ tcred->suid) &&
- (cred->euid ^ tcred->uid) &&
- (cred->uid ^ tcred->suid) &&
- (cred->uid ^ tcred->uid) &&
- !capable(CAP_KILL)) {
+ !kill_ok_by_cred(t)) {
switch (sig) {
case SIGCONT:
sid = task_session(t);
--
1.7.0.4
_______________________________________________
Containers mailing list
Containers at lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers
More information about the Devel
mailing list