Skip to content

Commit

Permalink
cgroup: implement the PIDs subsystem
Browse files Browse the repository at this point in the history
Adds a new single-purpose PIDs subsystem to limit the number of
tasks that can be forked inside a cgroup. Essentially this is an
implementation of RLIMIT_NPROC that applies to a cgroup rather than a
process tree.

However, it should be noted that organisational operations (adding and
removing tasks from a PIDs hierarchy) will *not* be prevented. Rather,
the number of tasks in the hierarchy cannot exceed the limit through
forking. This is due to the fact that, in the unified hierarchy, attach
cannot fail (and it is not possible for a task to overcome its PIDs
cgroup policy limit by attaching to a child cgroup -- even if migrating
mid-fork it must be able to fork in the parent first).

PIDs are fundamentally a global resource, and it is possible to reach
PID exhaustion inside a cgroup without hitting any reasonable kmemcg
policy. Once you've hit PID exhaustion, you're only in a marginally
better state than OOM. This subsystem allows PID exhaustion inside a
cgroup to be prevented.

Signed-off-by: Aleksa Sarai <[email protected]>
Signed-off-by: Tejun Heo <[email protected]>
  • Loading branch information
cyphar authored and htejun committed Jul 14, 2015
1 parent 7e47682 commit 49b786e
Show file tree
Hide file tree
Showing 5 changed files with 393 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CREDITS
Original file line number Diff line number Diff line change
Expand Up @@ -3219,6 +3219,11 @@ S: 69 rue Dunois
S: 75013 Paris
S: France

N: Aleksa Sarai
E: [email protected]
W: https://www.cyphar.com/
D: `pids` cgroup subsystem

N: Dipankar Sarma
E: [email protected]
D: RCU
Expand Down
5 changes: 5 additions & 0 deletions include/linux/cgroup_subsys.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ SUBSYS(hugetlb)
* Subsystems that implement the can_fork() family of callbacks.
*/
SUBSYS_TAG(CANFORK_START)

#if IS_ENABLED(CONFIG_CGROUP_PIDS)
SUBSYS(pids)
#endif

SUBSYS_TAG(CANFORK_END)

/*
Expand Down
16 changes: 16 additions & 0 deletions init/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,22 @@ config CGROUP_FREEZER
Provides a way to freeze and unfreeze all tasks in a
cgroup.

config CGROUP_PIDS
bool "PIDs cgroup subsystem"
help
Provides enforcement of process number limits in the scope of a
cgroup. Any attempt to fork more processes than is allowed in the
cgroup will fail. PIDs are fundamentally a global resource because it
is fairly trivial to reach PID exhaustion before you reach even a
conservative kmemcg limit. As a result, it is possible to grind a
system to halt without being limited by other cgroup policies. The
PIDs cgroup subsystem is designed to stop this from happening.

It should be noted that organisational operations (such as attaching
to a cgroup hierarchy will *not* be blocked by the PIDs subsystem),
since the PIDs limit only affects a process's ability to fork, not to
attach to a cgroup.

config CGROUP_DEVICE
bool "Device controller for cgroups"
help
Expand Down
1 change: 1 addition & 0 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ obj-$(CONFIG_BACKTRACE_SELF_TEST) += backtracetest.o
obj-$(CONFIG_COMPAT) += compat.o
obj-$(CONFIG_CGROUPS) += cgroup.o
obj-$(CONFIG_CGROUP_FREEZER) += cgroup_freezer.o
obj-$(CONFIG_CGROUP_PIDS) += cgroup_pids.o
obj-$(CONFIG_CPUSETS) += cpuset.o
obj-$(CONFIG_UTS_NS) += utsname.o
obj-$(CONFIG_USER_NS) += user_namespace.o
Expand Down
Loading

0 comments on commit 49b786e

Please sign in to comment.