From: Aleksa Sarai <cyphar@cyphar.com>
To: tj@kernel.org, lizefan@huawei.com, mingo@redhat.com,
peterz@infradead.org
Cc: richard@nod.at, fweisbec@gmail.com, linux-kernel@vger.kernel.org,
cgroups@vger.kernel.org, Aleksa Sarai <cyphar@cyphar.com>
Subject: [PATCH v4 1/2] cgroups: allow a cgroup subsystem to reject a fork
Date: Fri, 6 Mar 2015 12:45:56 +1100 [thread overview]
Message-ID: <1425606357-6337-2-git-send-email-cyphar@cyphar.com> (raw)
In-Reply-To: <1425606357-6337-1-git-send-email-cyphar@cyphar.com>
Add a new cgroup subsystem callback can_fork that conditionally
states whether or not the fork is accepted or rejected with a cgroup
policy.
Make the cgroup subsystem can_fork callback return an error code so
that subsystems can accept or reject a fork from completing with a
custom error value, before the process is exposed.
In addition, add a cancel_fork callback so that if an error occurs later
in the forking process, any state modified by can_fork can be reverted.
In order for can_fork to deal with a task that has an accurate css_set,
move the css_set updating to cgroup_fork (where it belongs).
This is in preparation for implementing the pids cgroup subsystem.
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
---
include/linux/cgroup.h | 9 ++++++
kernel/cgroup.c | 82 ++++++++++++++++++++++++++++++++++++++++----------
kernel/fork.c | 12 +++++++-
3 files changed, 86 insertions(+), 17 deletions(-)
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index b9cb94c..43ed1ee 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -32,6 +32,8 @@ struct cgroup;
extern int cgroup_init_early(void);
extern int cgroup_init(void);
extern void cgroup_fork(struct task_struct *p);
+extern int cgroup_can_fork(struct task_struct *p);
+extern void cgroup_cancel_fork(struct task_struct *p);
extern void cgroup_post_fork(struct task_struct *p);
extern void cgroup_exit(struct task_struct *p);
extern int cgroupstats_build(struct cgroupstats *stats,
@@ -649,6 +651,8 @@ struct cgroup_subsys {
struct cgroup_taskset *tset);
void (*attach)(struct cgroup_subsys_state *css,
struct cgroup_taskset *tset);
+ int (*can_fork)(struct task_struct *task);
+ void (*cancel_fork)(struct task_struct *task);
void (*fork)(struct task_struct *task);
void (*exit)(struct cgroup_subsys_state *css,
struct cgroup_subsys_state *old_css,
@@ -948,6 +952,11 @@ struct cgroup_subsys_state;
static inline int cgroup_init_early(void) { return 0; }
static inline int cgroup_init(void) { return 0; }
static inline void cgroup_fork(struct task_struct *p) {}
+static inline int cgroup_can_fork(struct task_struct *p)
+{
+ return 0;
+}
+static inline void cgroup_cancel_fork(struct task_struct *p) {}
static inline void cgroup_post_fork(struct task_struct *p) {}
static inline void cgroup_exit(struct task_struct *p) {}
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 29a7b2c..378badb 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -182,6 +182,9 @@ static u64 css_serial_nr_next = 1;
*/
static int need_forkexit_callback __read_mostly;
+/* Ditto for the can_fork/cancel_fork callbacks. */
+static int need_canfork_callback __read_mostly;
+
static struct cftype cgroup_dfl_base_files[];
static struct cftype cgroup_legacy_base_files[];
@@ -4933,6 +4936,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss, bool early)
init_css_set.subsys[ss->id] = css;
need_forkexit_callback |= ss->fork || ss->exit;
+ need_canfork_callback |= ss->can_fork || ss->cancel_fork;
/* At system boot, before all subsystems have been
* registered, no tasks have been forked, so we don't
@@ -5183,22 +5187,6 @@ void cgroup_fork(struct task_struct *child)
{
RCU_INIT_POINTER(child->cgroups, &init_css_set);
INIT_LIST_HEAD(&child->cg_list);
-}
-
-/**
- * cgroup_post_fork - called on a new task after adding it to the task list
- * @child: the task in question
- *
- * Adds the task to the list running through its css_set if necessary and
- * call the subsystem fork() callbacks. Has to be after the task is
- * visible on the task list in case we race with the first call to
- * cgroup_task_iter_start() - to guarantee that the new task ends up on its
- * list.
- */
-void cgroup_post_fork(struct task_struct *child)
-{
- struct cgroup_subsys *ss;
- int i;
/*
* This may race against cgroup_enable_task_cg_lists(). As that
@@ -5233,6 +5221,68 @@ void cgroup_post_fork(struct task_struct *child)
}
up_write(&css_set_rwsem);
}
+}
+
+/**
+ * cgroup_can_fork - called on a new task before the process is exposed.
+ * @child: the task in question.
+ *
+ * This calls the subsystem can_fork() callbacks. If the can_fork() callback
+ * returns an error, the fork aborts with that error code. This allows for
+ * a cgroup subsystem to conditionally allow or deny new forks.
+ */
+int cgroup_can_fork(struct task_struct *child)
+{
+ struct cgroup_subsys *ss;
+ int i;
+
+ if (need_canfork_callback) {
+ int retval;
+
+ for_each_subsys(ss, i)
+ if (ss->can_fork) {
+ retval = ss->can_fork(child);
+ if (retval)
+ return retval;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * cgroup_cancel_fork - called if a fork failed after cgroup_can_fork()
+ * @child: the task in question
+ *
+ * This calls the cancel_fork() callbacks if a fork failed *after*
+ * cgroup_can_fork() succeded.
+ */
+void cgroup_cancel_fork(struct task_struct *child)
+{
+ struct cgroup_subsys *ss;
+ int i;
+
+ if (need_canfork_callback) {
+ for_each_subsys(ss, i)
+ if (ss->cancel_fork)
+ ss->cancel_fork(child);
+ }
+}
+
+/**
+ * cgroup_post_fork - called on a new task after adding it to the task list
+ * @child: the task in question
+ *
+ * Adds the task to the list running through its css_set if necessary and
+ * call the subsystem fork() callbacks. Has to be after the task is
+ * visible on the task list in case we race with the first call to
+ * cgroup_task_iter_start() - to guarantee that the new task ends up on its
+ * list.
+ */
+void cgroup_post_fork(struct task_struct *child)
+{
+ struct cgroup_subsys *ss;
+ int i;
/*
* Call ss->fork(). This must happen after @child is linked on
diff --git a/kernel/fork.c b/kernel/fork.c
index cf65139..35850a9 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1469,6 +1469,14 @@ static struct task_struct *copy_process(unsigned long clone_flags,
p->task_works = NULL;
/*
+ * Ensure that the cgroup subsystem policies allow the new process to be
+ * forked.
+ */
+ retval = cgroup_can_fork(p);
+ if (retval)
+ goto bad_fork_free_pid;
+
+ /*
* Make it visible to the rest of the system, but dont wake it up yet.
* Need tasklist lock for parent etc handling!
*/
@@ -1504,7 +1512,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
spin_unlock(¤t->sighand->siglock);
write_unlock_irq(&tasklist_lock);
retval = -ERESTARTNOINTR;
- goto bad_fork_free_pid;
+ goto bad_fork_cgroup_cancel;
}
if (likely(p->pid)) {
@@ -1556,6 +1564,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
return p;
+bad_fork_cgroup_cancel:
+ cgroup_cancel_fork(p);
bad_fork_free_pid:
if (pid != &init_struct_pid)
free_pid(pid);
--
2.3.1
next prev parent reply other threads:[~2015-03-06 1:45 UTC|newest]
Thread overview: 108+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-23 3:08 [PATCH RFC 0/2] add nproc cgroup subsystem Aleksa Sarai
2015-02-23 3:08 ` Aleksa Sarai
2015-02-23 3:08 ` [PATCH RFC 1/2] cgroups: allow a cgroup subsystem to reject a fork Aleksa Sarai
2015-02-23 14:49 ` Peter Zijlstra
2015-02-23 3:08 ` [PATCH RFC 2/2] cgroups: add an nproc subsystem Aleksa Sarai
[not found] ` <1424660891-12719-1-git-send-email-cyphar-gVpy/LI/lHzQT0dZR+AlfA@public.gmane.org>
2015-02-27 4:17 ` [RFC PATCH v2 0/2] add nproc cgroup subsystem Aleksa Sarai
2015-02-27 4:17 ` Aleksa Sarai
[not found] ` <1425010639-16492-1-git-send-email-cyphar-gVpy/LI/lHzQT0dZR+AlfA@public.gmane.org>
2015-02-27 4:17 ` [PATCH v2 1/2] cgroups: allow a cgroup subsystem to reject a fork Aleksa Sarai
2015-02-27 4:17 ` Aleksa Sarai
[not found] ` <1425010639-16492-2-git-send-email-cyphar-gVpy/LI/lHzQT0dZR+AlfA@public.gmane.org>
2015-03-09 3:06 ` Tejun Heo
2015-03-09 3:06 ` Tejun Heo
[not found] ` <CAOviyaip7Faz98YWzGoTaXGYVb72sfD+ZL4Xa89reU9+=43jFA@mail.gmail.com>
[not found] ` <20150309065902.GP13283@htj.duckdns.org>
[not found] ` <20150309065902.GP13283-piEFEHQLUPpN0TnZuCh8vA@public.gmane.org>
2015-03-10 8:19 ` Aleksa Sarai
2015-03-10 8:19 ` Aleksa Sarai
[not found] ` <CAOviyaj3mf66ho15WrD8qB=ECxKWYTAkWodxWaFVMWeZG4d0FQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-03-10 12:47 ` Tejun Heo
2015-03-10 12:47 ` Tejun Heo
[not found] ` <20150310124701.GB28730-piEFEHQLUPpN0TnZuCh8vA@public.gmane.org>
2015-03-10 14:51 ` Aleksa Sarai
2015-03-10 14:51 ` Aleksa Sarai
[not found] ` <CAOviyai7yJrbGb+uYpK35tw7R-KM0jWQ-BmhpyTqnRFJsVYdUA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-03-10 15:17 ` Tejun Heo
2015-03-10 15:17 ` Tejun Heo
2015-03-11 5:16 ` Aleksa Sarai
2015-03-11 11:46 ` Tejun Heo
2015-03-11 23:47 ` Aleksa Sarai
2015-03-11 23:47 ` Aleksa Sarai
[not found] ` <CAOviyaj55Yqahz75Gy5=yjFteeKFp7746=80-Ufww2E62Ads_Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-03-12 1:25 ` Tejun Heo
2015-03-12 1:25 ` Tejun Heo
2015-02-27 4:17 ` [PATCH v2 2/2] cgroups: add an nproc subsystem Aleksa Sarai
[not found] ` <1425010639-16492-3-git-send-email-cyphar-gVpy/LI/lHzQT0dZR+AlfA@public.gmane.org>
2015-03-02 15:22 ` Tejun Heo
2015-03-02 15:22 ` Tejun Heo
[not found] ` <20150302152205.GC17694-piEFEHQLUPpN0TnZuCh8vA@public.gmane.org>
2015-03-09 1:49 ` Zefan Li
2015-03-09 1:49 ` Zefan Li
[not found] ` <54FCFC39.6050900-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
2015-03-09 2:34 ` Tejun Heo
2015-03-09 2:34 ` Tejun Heo
2015-03-06 1:45 ` [PATCH v4 0/2] cgroup: add pids subsystem Aleksa Sarai
2015-03-06 1:45 ` Aleksa Sarai
2015-03-06 1:45 ` Aleksa Sarai [this message]
[not found] ` <1425606357-6337-1-git-send-email-cyphar-gVpy/LI/lHzQT0dZR+AlfA@public.gmane.org>
2015-03-06 1:45 ` [PATCH v4 2/2] cgroups: add a " Aleksa Sarai
2015-03-06 1:45 ` Aleksa Sarai
[not found] ` <1425606357-6337-3-git-send-email-cyphar-gVpy/LI/lHzQT0dZR+AlfA@public.gmane.org>
2015-03-09 3:34 ` Tejun Heo
2015-03-09 3:34 ` Tejun Heo
[not found] ` <20150309033405.GE13283-piEFEHQLUPpN0TnZuCh8vA@public.gmane.org>
2015-03-09 3:39 ` Tejun Heo
2015-03-09 3:39 ` Tejun Heo
2015-03-09 18:58 ` Austin S Hemmelgarn
2015-03-09 18:58 ` Austin S Hemmelgarn
[not found] ` <54FDED43.4050908-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-03-09 19:51 ` Tejun Heo
2015-03-09 19:51 ` Tejun Heo
2015-03-10 8:10 ` Aleksa Sarai
2015-03-10 8:10 ` Aleksa Sarai
2015-03-10 11:32 ` Austin S Hemmelgarn
[not found] ` <54FED651.6040100-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-03-10 12:31 ` Aleksa Sarai
2015-03-10 12:31 ` Aleksa Sarai
[not found] ` <CAOviyagpCNcAN4hdhsxffdpE+yDmw+NXx+FikTe64GJ1hQeXhQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-03-11 15:13 ` Austin S Hemmelgarn
2015-03-11 15:13 ` Austin S Hemmelgarn
[not found] ` <55005BAC.9060405-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-03-12 2:28 ` Aleksa Sarai
2015-03-12 2:28 ` Aleksa Sarai
2015-03-12 15:35 ` Austin S Hemmelgarn
2015-03-12 3:47 ` Tejun Heo
2015-03-09 3:08 ` [PATCH v4 0/2] cgroup: add " Tejun Heo
2015-03-09 3:08 ` Tejun Heo
2015-02-27 11:49 ` [PATCH RFC 0/2] add nproc cgroup subsystem Tejun Heo
[not found] ` <20150227114940.GB3964-piEFEHQLUPpN0TnZuCh8vA@public.gmane.org>
2015-02-27 13:46 ` Richard Weinberger
2015-02-27 13:46 ` Richard Weinberger
[not found] ` <54F07525.4050100-/L3Ra7n9ekc@public.gmane.org>
2015-02-27 13:52 ` Tejun Heo
2015-02-27 13:52 ` Tejun Heo
2015-02-27 16:42 ` Austin S Hemmelgarn
2015-02-27 16:42 ` Austin S Hemmelgarn
[not found] ` <54F09E62.8000007-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-02-27 17:06 ` Tejun Heo
2015-02-27 17:06 ` Tejun Heo
[not found] ` <20150227170640.GK3964-piEFEHQLUPpN0TnZuCh8vA@public.gmane.org>
2015-02-27 17:25 ` Tim Hockin
2015-02-27 17:25 ` Tim Hockin
2015-02-27 17:45 ` Tejun Heo
[not found] ` <20150227174503.GM3964-piEFEHQLUPpN0TnZuCh8vA@public.gmane.org>
2015-02-27 17:56 ` Tejun Heo
2015-02-27 17:56 ` Tejun Heo
2015-02-27 21:45 ` Tim Hockin
2015-02-27 21:45 ` Tim Hockin
2015-02-27 21:49 ` Tejun Heo
[not found] ` <CAAAKZwsCc8BtFx58KMFpRTohU81oCBeGVOPGMJrjJt9q5upKfQ@mail.gmail.com>
2015-02-28 16:57 ` Tejun Heo
[not found] ` <20150228165706.GS3964-piEFEHQLUPpN0TnZuCh8vA@public.gmane.org>
2015-02-28 22:26 ` Tim Hockin
2015-02-28 22:26 ` Tim Hockin
[not found] ` <CAAAKZwv=idxvrffHx2QyW=PGH4k42ckq-VLJGQrXkeQ6NmByRQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-02-28 22:50 ` Tejun Heo
2015-02-28 22:50 ` Tejun Heo
[not found] ` <20150228225036.GA4597-piEFEHQLUPpN0TnZuCh8vA@public.gmane.org>
2015-03-01 4:46 ` Tim Hockin
2015-03-01 4:46 ` Tim Hockin
2015-02-28 23:11 ` Johannes Weiner
2015-02-28 23:11 ` Johannes Weiner
2015-02-27 18:49 ` Austin S Hemmelgarn
2015-02-27 18:49 ` Austin S Hemmelgarn
[not found] ` <54F0BC51.4050506-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-02-27 19:35 ` Tejun Heo
2015-02-27 19:35 ` Tejun Heo
2015-02-28 9:26 ` Aleksa Sarai
2015-02-28 9:26 ` Aleksa Sarai
[not found] ` <CAOviyajSOY6kTiwTA+APf9VGT=Ui=0QQH6KUqwaxHB3ahuJk2g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-02-28 11:59 ` Tejun Heo
2015-02-28 11:59 ` Tejun Heo
[not found] ` <CAAAKZws45c3PhFQMGrm_K+OZV+KOyGV9sXTakHcTfNP1kHxzOQ@mail.gmail.com>
[not found] ` <CAAAKZws45c3PhFQMGrm_K+OZV+KOyGV9sXTakHcTfNP1kHxzOQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-02-28 16:43 ` Tejun Heo
2015-02-28 16:43 ` Tejun Heo
2015-03-02 13:13 ` Austin S Hemmelgarn
[not found] ` <54F461F3.3030903-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-03-02 13:31 ` Aleksa Sarai
2015-03-02 13:31 ` Aleksa Sarai
[not found] ` <CAOviyahKJthwLTND51HhaRNB_KJC60T7HFHjdqPZf3pQmAUAhw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-03-02 13:54 ` Tejun Heo
2015-03-02 13:54 ` Tejun Heo
2015-03-02 13:49 ` Tejun Heo
2015-02-27 17:12 ` Tim Hockin
[not found] ` <CAO_RewbeTbMuqVG5wsui_gHwrdgqjF0KLk6yr5a3bb76VOkofg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-02-27 17:15 ` Tejun Heo
2015-02-27 17:15 ` Tejun Heo
2015-03-04 20:23 ` [PATCH v3 0/2] cgroup: add pids subsystem Aleksa Sarai
2015-03-04 20:23 ` [PATCH v3 1/2] cgroups: allow a cgroup subsystem to reject a fork Aleksa Sarai
2015-03-04 20:23 ` [PATCH v3 2/2] cgroups: add a pids subsystem Aleksa Sarai
2015-03-05 8:39 ` Aleksa Sarai
2015-03-05 14:37 ` Marian Marinov
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=1425606357-6337-2-git-send-email-cyphar@cyphar.com \
--to=cyphar@cyphar.com \
--cc=cgroups@vger.kernel.org \
--cc=fweisbec@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lizefan@huawei.com \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=richard@nod.at \
--cc=tj@kernel.org \
/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.