summaryrefslogtreecommitdiff
path: root/lib/supple/capi.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/supple/capi.c')
-rw-r--r--lib/supple/capi.c53
1 files changed, 53 insertions, 0 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;
}