Linux System Programming · intermediate · ~15 min
Set resource limits on yourself before privilege escalation or sandbox.
setrlimit puts a per-process cap on a resource. Once you lower the hard limit, only root can raise it again. Used to drop your own privileges before running risky code.
Sandboxing in C starts with rlimits. Every Docker, every CI runner, every code-execution service tweaks them.
RLIMIT_AS. Total address space (anonymous + mmap'd). Caps malloc.
RLIMIT_CPU. CPU seconds. SIGXCPU when soft hits, SIGKILL on hard.
RLIMIT_FSIZE. Max file write size. SIGXFSZ on overrun.
RLIMIT_NOFILE. Open file descriptor count.
RLIMIT_NPROC. Per-user process count.
Pentester mindset. When auditing a sandbox runner, check whether it sets rlimits. Missing RLIMIT_CPU = an attacker can pin a core forever. Missing RLIMIT_AS = OOM.
Defensive coding habit. Lower BOTH soft and hard limits at the start of a privileged-then-dropped section. Never raise a hard limit you set yourself.
#include <sys/resource.h>
int getrlimit(int resource, struct rlimit *rlim);
int setrlimit(int resource, const struct rlimit *rlim);
setrlimit / getrlimit configure per-process resource caps: CPU
seconds, address space, file size, number of open fds. They are how the
user-space side of every sandbox is built — 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);
ulimit -a in a shell shows your current limits. prlimit --pid PID queries any process. cat /proc/PID/limits is the kernel's view.
Setting RLIMIT_AS too low can make later malloc fail unexpectedly. Test under load.
Every code runner. Every cgroup ancestor. Every shell builtin ulimit.
setrlimit caps a per-process resource. Lower the hard limit to drop forever. The kernel side of every sandbox.