summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2012-08-04 18:16:52 +0100
committerDaniel Silverstone <dsilvers@digital-scurf.org>2012-08-04 18:16:52 +0100
commitfaf3c8b4964fdc3b0c6cf04fa62209d8feb75970 (patch)
tree335c837dc1e136bf6eb1f2d7950cb583e4ca0dca
parent21efd074399894bd9b924177f8c6fde874bb036a (diff)
downloadsupple-faf3c8b4964fdc3b0c6cf04fa62209d8feb75970.tar.gz
SUPPLE: If we're on Linux we can lock ourselves down into seccomp mode 1 with some mallopt trickery
-rw-r--r--lib/supple/capi.c53
-rw-r--r--lib/supple/sandbox.lua10
2 files changed, 57 insertions, 6 deletions
diff --git a/lib/supple/capi.c b/lib/supple/capi.c
index 97802ec..125a415 100644
--- a/lib/supple/capi.c
+++ b/lib/supple/capi.c
@@ -21,6 +21,10 @@
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
+#ifdef linux
+#include <sys/prctl.h>
+#include <malloc.h>
+#endif
/* The API exposed, increment on backward-compatible changes */
#define CAPI_API 1
@@ -254,6 +258,30 @@ supple_capi_lockdown(lua_State *L)
} \
} while (0)
+#ifdef linux
+ /* Have a go at ensuring we won't call brk() ready for seccomp() */
+ if (rootly && prctl(PR_GET_SECCOMP, 0, 0, 0, 0) == 0) {
+ /* We might be able to enter seccomp mode 1, so carry on */
+ /* Disable returning memory to the OS */
+ if (mallopt(M_TRIM_THRESHOLD, -1) == 0) {
+ int saved_errno = errno;
+ lua_pushliteral(L, "mallopt(M_TRIM_THRESHOLD)");
+ lua_pushnumber(L, saved_errno);
+ return 2;
+ }
+ /* Disable allocating memory by mmap() */
+ if (mallopt(M_MMAP_MAX, 0) == 0) {
+ int saved_errno = errno;
+ lua_pushliteral(L, "mallopt(M_MMAP_MAX)");
+ lua_pushnumber(L, saved_errno);
+ return 2;
+ }
+ /* Now allocate/free a big chunk of RAM */
+ free(malloc(20 * 1024 * 1024));
+ }
+#endif
+ /* Regardless of OS, we'll now try and set off some limits */
+
/* 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)
@@ -281,8 +309,33 @@ supple_capi_lockdown(lua_State *L)
lua_pushnumber(L, saved_errno);
return 2;
}
+
+#ifdef linux
+ /* Next, we're going to attempt a seccomp setup */
+ if (rootly) {
+ /* We're fairly well locked down, however with Linux we
+ * can go one step further and enter 'seccomp mode 1' which
+ * limits our syscalls to read/write/_exit/sigreturn.
+ *
+ * This means that even if the attacker breaks out harder
+ * than we can imagine, their *ONLY* avenue of attack is
+ * back along the already open FD to the host app.
+ */
+ if (prctl(PR_SET_SECCOMP, 1, 0, 0, 0) != 0) {
+ int saved_errno = errno;
+ lua_pushliteral(L, "prctl(PR_SET_SECCOMP, 1)");
+ lua_pushnumber(L, saved_errno);
+ return 2;
+ }
+ }
+ /* If we reach here and we're rootly, we need to inform the lib
+ * Not to do the open() test or we get killed
+ */
+ lua_pushstring(L, (rootly ? "OK" : "oknonroot"));
+#else
lua_pushstring(L, (rootly ? "ok" : "oknonroot"));
+#endif
lua_pushnumber(L, 0);
return 2;
}
diff --git a/lib/supple/sandbox.lua b/lib/supple/sandbox.lua
index 57e5cd3..6a79348 100644
--- a/lib/supple/sandbox.lua
+++ b/lib/supple/sandbox.lua
@@ -78,7 +78,7 @@ local function run()
-- Run the sandbox
local result, errno = capi.lockdown()
- if result ~= "ok"
+ if result ~= "ok" and result ~= "OK"
-- START_TEST_ONLY
and result ~= "oknonroot"
-- END_TEST_ONLY
@@ -88,9 +88,9 @@ local function run()
return errno
end
--- START_TEST_ONLY
- if result ~= "oknonroot" then
--- END_TEST_ONLY
+ if result == "ok" then
+ -- Note, if result is "OK" then we're pretty hard jailed
+ -- and cannot even do this test lest we get killed
-- Check that we're definitely solidly jailed
fh, errno = sio.open("testfile", "rw")
if fh then
@@ -98,9 +98,7 @@ local function run()
luxio.unlink("testfile")
return 1
end
--- START_TEST_ONLY
end
--- END_TEST_ONLY
-- Prepare a severely limited sandbox
local sandbox_globals = {