From: Dhaval Giani <dhaval@linux.vnet.ibm.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Corey Hickey <bugfood-ml@fatooh.org>,
linux-kernel@vger.kernel.org,
Bharata B Rao <bharata@linux.vnet.ibm.com>,
Balbir Singh <balbir@in.ibm.com>,
Srivatsa Vaddagiri <vatsa@linux.vnet.ibm.com>,
Ingo Molnar <mingo@elte.hu>,
mtk.manpages@gmail.com
Subject: Re: RT scheduling and a way to make a process hang, unkillable
Date: Mon, 16 Feb 2009 16:06:36 +0530 [thread overview]
Message-ID: <20090216103636.GC17355@linux.vnet.ibm.com> (raw)
In-Reply-To: <1234697096.4713.24.camel@laptop>
On Sun, Feb 15, 2009 at 12:24:56PM +0100, Peter Zijlstra wrote:
> On Sat, 2009-02-14 at 16:51 -0800, Corey Hickey wrote:
> > Hello,
> >
> > I've encountered a bit of a problem in recent kernels that include
> > "Group scheduling for SCHED_RR/FIFO": it is possible for a process run
> > by root to hang itself and become unkillable--even by a 'kill -9'.
> >
> > The following kernel options must be set:
> > CONFIG_GROUP_SCHED=y
> > CONFIG_RT_GROUP_SCHED=y
> > CONFIG_USER_SCHED=y
> >
> > The procedure is for a program to:
> > 1. run as root
> > 2. set SCHED_FIFO
> > 3. change UID to a user with no realtime CPU share allocated
>
> Hmm, setuid() should fail in that situation.
>
> /me goes peek at code.
>
> Can't find any code to make that happen, Dhaval didn't we fix that at
> one point?
So after some searching around, I realized we did not. Does this help?
It fixes it on my system,
--
sched: Don't allow setuid to succeed if the user does not have rt bandwidth
Corey Hickey reported that on using setuid to change the uid of a
rt process, the process would be unkillable and not be running.
This is because there was no rt runtime for that user group. Add
in a check to see if a user can attach an rt task to its task group.
Disclaimer: Not sure about the return values, and if setuid allows
return values other than EPERM and EAGAIN.
Not-Yet-Signed-off-by: Dhaval Giani <dhaval@linux.vnet.ibm.com>
Index: linux-2.6/include/linux/sched.h
===================================================================
--- linux-2.6.orig/include/linux/sched.h
+++ linux-2.6/include/linux/sched.h
@@ -2320,9 +2320,12 @@ extern long sched_group_rt_runtime(struc
extern int sched_group_set_rt_period(struct task_group *tg,
long rt_period_us);
extern long sched_group_rt_period(struct task_group *tg);
+int sched_rt_can_attach(struct task_group *tg, struct task_struct *tsk);
#endif
#endif
+int rt_task_can_switch_user(uid_t uid, struct task_struct *tsk);
+
#ifdef CONFIG_TASK_XACCT
static inline void add_rchar(struct task_struct *tsk, ssize_t amt)
{
Index: linux-2.6/kernel/sched.c
===================================================================
--- linux-2.6.orig/kernel/sched.c
+++ linux-2.6/kernel/sched.c
@@ -9466,6 +9466,16 @@ static int sched_rt_global_constraints(v
return ret;
}
+
+int sched_rt_can_attach(struct task_group *tg, struct task_struct *tsk)
+{
+ /* Don't accept realtime tasks when there is no way for them to run */
+ if (rt_task(tsk) && tg->rt_bandwidth.rt_runtime == 0)
+ return -EINVAL;
+
+ return 0;
+}
+
#else /* !CONFIG_RT_GROUP_SCHED */
static int sched_rt_global_constraints(void)
{
@@ -9559,8 +9569,7 @@ cpu_cgroup_can_attach(struct cgroup_subs
struct task_struct *tsk)
{
#ifdef CONFIG_RT_GROUP_SCHED
- /* Don't accept realtime tasks when there is no way for them to run */
- if (rt_task(tsk) && cgroup_tg(cgrp)->rt_bandwidth.rt_runtime == 0)
+ if (sched_rt_can_attach(cgroup_tg(cgrp), tsk))
return -EINVAL;
#else
/* We don't support RT-tasks being in separate groups */
Index: linux-2.6/kernel/user.c
===================================================================
--- linux-2.6.orig/kernel/user.c
+++ linux-2.6/kernel/user.c
@@ -216,8 +216,28 @@ static ssize_t cpu_rt_period_store(struc
static struct kobj_attribute cpu_rt_period_attr =
__ATTR(cpu_rt_period, 0644, cpu_rt_period_show, cpu_rt_period_store);
+
#endif
+#ifdef CONFIG_RT_GROUP_SCHED && CONFIG_USER_SCHED
+/*
+ * We need to check if a setuid can take place. This function should be called
+ * before successfully completing the setuid.
+ */
+
+int rt_task_can_switch_user(uid_t uid, struct task_struct *tsk)
+{
+ struct user_struct *up = find_user(uid);
+
+ return sched_rt_can_attach(up->tg, tsk);
+}
+#else
+int rt_task_can_switch_user(uid_t uid, struct task_struct *tsk)
+{
+ return 0;
+}
+
+#endif
/* default attributes per uid directory */
static struct attribute *uids_attributes[] = {
#ifdef CONFIG_FAIR_GROUP_SCHED
Index: linux-2.6/kernel/sys.c
===================================================================
--- linux-2.6.orig/kernel/sys.c
+++ linux-2.6/kernel/sys.c
@@ -579,6 +579,15 @@ static int set_user(struct cred *new)
return -EAGAIN;
}
+ /*
+ * Though rt_task_can_switch_user returns EINVAL on failure, we
+ * return EAGAIN so as not to break semantics and because
+ * EAGAIN implies resource not available which is the case in
+ * this case.
+ */
+ if (rt_task_can_switch_user(new->uid, current))
+ return -EAGAIN;
+
free_uid(new->user);
new->user = new_user;
return 0;
--
regards,
Dhaval
next prev parent reply other threads:[~2009-02-16 10:37 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-02-15 0:51 RT scheduling and a way to make a process hang, unkillable Corey Hickey
2009-02-15 11:24 ` Peter Zijlstra
2009-02-16 10:36 ` Dhaval Giani [this message]
2009-02-16 11:08 ` Peter Zijlstra
2009-02-16 12:02 ` Dhaval Giani
2009-02-16 12:24 ` Peter Zijlstra
2009-02-16 13:14 ` Dhaval Giani
2009-02-16 13:19 ` Peter Zijlstra
2009-02-16 14:23 ` Peter Zijlstra
2009-02-16 13:20 ` Dhaval Giani
2009-02-16 19:18 ` Corey Hickey
2009-02-17 5:00 ` Dhaval Giani
2009-02-17 10:15 ` Dhaval Giani
2009-02-17 11:15 ` Peter Zijlstra
2009-02-18 0:09 ` Corey Hickey
2009-02-23 11:45 ` Dhaval Giani
2009-02-23 11:59 ` Peter Zijlstra
2009-02-24 9:18 ` Dhaval Giani
2009-02-24 15:58 ` Andi Kleen
2009-02-24 16:36 ` Peter Zijlstra
2009-02-24 19:29 ` Chris Friesen
2009-02-27 9:43 ` [PATCH] sched: Don't allow setuid to succeed if the user does not have rt bandwidth Dhaval Giani
2009-02-27 10:25 ` Ingo Molnar
2009-02-16 20:16 ` RT scheduling and a way to make a process hang, unkillable Kyle Moffett
2009-02-16 20:28 ` Peter Zijlstra
2009-02-17 7:22 ` Dhaval Giani
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090216103636.GC17355@linux.vnet.ibm.com \
--to=dhaval@linux.vnet.ibm.com \
--cc=balbir@in.ibm.com \
--cc=bharata@linux.vnet.ibm.com \
--cc=bugfood-ml@fatooh.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=mtk.manpages@gmail.com \
--cc=peterz@infradead.org \
--cc=vatsa@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.