Linux System Programming · intermediate · ~15 min
Learn to set resource limits on your own process before escalating privileges or entering a sandbox.
setrlimit puts a per-process cap on a single resource, such as memory or CPU time.
Each resource has two limits:
Once you lower the hard limit, only root can raise it again. This is a one-way door, which makes it useful for dropping your own privileges before running risky code.
Sandboxing in C starts with resource limits.
Every Docker container, every CI runner, and every code-execution service tunes them to keep workloads contained.
mmap'd regions). This effectively caps how much malloc can hand out.SIGXCPU when the soft limit is reached, and SIGKILL at the hard limit.SIGXFSZ.When auditing a sandbox runner, check whether it sets resource limits at all.
RLIMIT_CPU means an attacker can pin a CPU core forever.RLIMIT_AS means an attacker can exhaust memory and trigger the out-of-memory (OOM) killer.Lower both the soft and hard limits at the start of a section that runs with privileges before dropping them.
Never raise a hard limit that you set yourself. You cannot, unless you are root.
#include <sys/resource.h>
int getrlimit(int resource, struct rlimit *rlim);
int setrlimit(int resource, const struct rlimit *rlim);
getrlimit reads the current limits for a resource. setrlimit changes them.
setrlimit and getrlimit configure per-process resource caps: CPU seconds, address space, file size, and number of open file descriptors.
They are the user-space foundation of every sandbox, including ours.
struct rlimit r = { .rlim_cur = 128 * 1024 * 1024, .rlim_max = 128 * 1024 * 1024 };
setrlimit(RLIMIT_AS, &r); /* 128 MB max address space */
struct rlimit r;
r.rlim_cur = r.rlim_max = 5; /* 5 CPU-seconds */
setrlimit(RLIMIT_CPU, &r);
r.rlim_cur = r.rlim_max = 128 * 1024L * 1024L; /* 128 MB */
setrlimit(RLIMIT_AS, &r);
Several tools let you inspect resource limits:
ulimit -a in a shell shows your current limits.prlimit --pid PID queries any running process.cat /proc/PID/limits shows the kernel's view for a given process.Setting RLIMIT_AS too low can make a later malloc fail in ways you did not expect.
Always test under realistic load before relying on a tight limit.
Concrete uses: Resource limits are how a system stops one process from taking everything. A shell sets them via ulimit before launching a job; a container runtime applies them per workload; a build server caps memory so a runaway compile cannot swap the machine to a halt. RLIMIT_NOFILE is the limit servers raise before accepting thousands of connections, and RLIMIT_CORE decides whether a crash produces a core dump for debugging. Sandboxes — including the one grading these exercises — set CPU, memory and process limits so untrusted code cannot exhaust the host.
Professional best practices:
Beginner:
getrlimit before assuming what it is; defaults differ widely between systems.Intermediate:
setrlimit leaves the process unprotected.RLIMIT_AS to 128 MB, then watch a 200 MB malloc fail.RLIMIT_CPU to 5 seconds, then run an infinite loop and observe the process being killed.RLIMIT_NOFILE to 16, then watch the 17th open call fail.setrlimit caps a per-process resource (CPU, memory, file size, open fds).