diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-08-04 15:58:54 +0100 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-08-04 15:58:54 +0100 |
commit | 21efd074399894bd9b924177f8c6fde874bb036a (patch) | |
tree | 0a333bb468f7ce80023f22b6fbc03e6a022f19b5 /lib/supple | |
parent | 789f4fb4f3b9a916a0609616e222ecfa0af86a5f (diff) | |
download | supple-21efd074399894bd9b924177f8c6fde874bb036a.tar.gz |
CAPI: rlimit the process HARD so even if it evades soft limits, it's pretty stuffed
Diffstat (limited to 'lib/supple')
-rw-r--r-- | lib/supple/capi.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/lib/supple/capi.c b/lib/supple/capi.c index 0eaa372..97802ec 100644 --- a/lib/supple/capi.c +++ b/lib/supple/capi.c @@ -14,6 +14,8 @@ #include <lauxlib.h> #include <sys/types.h> +#include <sys/time.h> +#include <sys/resource.h> #include <string.h> #include <stdbool.h> #include <unistd.h> @@ -173,6 +175,7 @@ supple_capi_lockdown(lua_State *L) { bool rootly = (geteuid() == 0); char *tempdir; + struct rlimit lim; lua_settop(L, 0); /* Discard any arguments */ /* Prepare a copy of the tempdir template ready */ @@ -231,6 +234,46 @@ supple_capi_lockdown(lua_State *L) return 2; } + /* Cap our limits down as far as we can */ +#define CAP_AT(lval,cap) lval = (lval < cap) ? lval : cap +#define CAP_LIMIT(resource, soft, hard) \ + do { \ + if (rootly && getrlimit(resource, &lim) != 0) { \ + int saved_errno = errno; \ + lua_pushliteral(L, "getrlimit(" #resource ")"); \ + lua_pushnumber(L, saved_errno); \ + return 2; \ + } \ + CAP_AT(lim.rlim_cur,soft); \ + CAP_AT(lim.rlim_max,hard); \ + if (rootly && setrlimit(resource, &lim) != 0) { \ + int saved_errno = errno; \ + lua_pushliteral(L, "setrlimit(" #resource ")"); \ + lua_pushnumber(L, saved_errno); \ + return 2; \ + } \ + } while (0) + + /* Limit the virtual memory arena to 50 megs. + * While this might seem a lot, a bare lua5.1 interpreter plus Supple + * and deps seems to come to around 28MB VMSZ (although only 2MB res) + * because of shared libraries and the ilk. 50MB allows for up to + * 22MB of allocations beyond that, which seems fair. + */ + CAP_LIMIT(RLIMIT_AS, (50 * 1024 * 1024), (50 * 1024 * 1024)); + /* And limit CPU to 15 seconds, 30 if not otherwise handled */ + CAP_LIMIT(RLIMIT_CPU, 15, 30); + /* Cap output file size at 0 bytes, so even if we managed to open + * a file, writes would fail. + */ + CAP_LIMIT(RLIMIT_FSIZE, 0, 0); + /* Do not allow core files to be created */ + CAP_LIMIT(RLIMIT_CORE, 0, 0); + /* And the attackers would have to close their only FD to the outside + * world in order to open anything anyway. + */ + CAP_LIMIT(RLIMIT_NOFILE, 1, 1); + /* Drop privs */ if (rootly && setuid(getuid()) != 0) { int saved_errno = errno; |