about summary refs log tree commit diff stats
path: root/src/bindings
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-04-18 18:30:53 +0200
committerbptato <nincsnevem662@gmail.com>2024-04-18 18:30:53 +0200
commit38db6ab5be80b255fe40df715adc3b5852875cdd (patch)
tree328eada3b571e475903be0df61c5abf09c022d8b /src/bindings
parent5bb9542045ff6dbb6c357eb4dd0a7616dba33a9a (diff)
downloadchawan-38db6ab5be80b255fe40df715adc3b5852875cdd.tar.gz
sandbox: seccomp support on Linux
We use libseccomp, which is now a semi-mandatory dependency on Linux.
(You can still build without it, but only if you pass a scary long flag
to make.)

For this to work I had to disable getTimezoneOffset, which would
otherwise call localtime_r which in turn reads in some files from
/usr/share/zoneinfo.  To allow this we would have to give unrestricted
openat(2) access to buffer processes, which is unacceptable.

(Giving websites access to the local timezone is a fingerprinting vector
so if this ever gets fixed then it should be an opt-in config setting.)

This patch also includes misc fixes to buffer cloning, and fixes the
LIBEXECDIR override in the makefile so that it is actually useful.
Diffstat (limited to 'src/bindings')
-rw-r--r--src/bindings/libseccomp.nim49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/bindings/libseccomp.nim b/src/bindings/libseccomp.nim
new file mode 100644
index 00000000..81a6e969
--- /dev/null
+++ b/src/bindings/libseccomp.nim
@@ -0,0 +1,49 @@
+import std/macros
+
+const seccomp = (proc(): string =
+  let res = staticExec("pkg-config --libs --silence-errors libseccomp")
+  if res == "":
+    error("Couldn't find libseccomp on your computer!  Please install " &
+      "libseccomp (e.g. apt install libseccomp-dev), or build with " &
+      "`make CHA_DANGER_DISABLE_SANDBOX=1'.")
+  return res
+)()
+
+type
+  scmp_filter_ctx* = distinct pointer
+
+  scmp_datum_t* = uint64
+
+  scmp_compare* {.size: sizeof(cint).} = enum
+    N_SCMP_CMP_MIN = 0
+    SCMP_CMP_NE = 1 # not equal
+    SCMP_CMP_LT = 2 # less than
+    SCMP_CMP_LE = 3 # less than or equal
+    SCMP_CMP_EQ = 4 # equal
+    SCMP_CMP_GE = 5 # greater than or equal
+    SCMP_CMP_GT = 6 # greater than
+    SCMP_CMP_MASKED_EQ = 7 # masked equality
+
+  scmp_arg_cmp* = object
+    arg*: cuint
+    op*: scmp_compare
+    datum_a*: scmp_datum_t
+    datum_b*: scmp_datum_t
+
+{.push importc.}
+{.passl: seccomp.}
+
+const SCMP_ACT_KILL_PROCESS* = 0x80000000u32
+const SCMP_ACT_ALLOW* = 0x7FFF0000u32
+const SCMP_ACT_TRAP* = 0x00030000u32
+
+proc seccomp_init*(def_action: uint32): scmp_filter_ctx
+proc seccomp_reset*(ctx: scmp_filter_ctx; def_action: uint32): cint
+proc seccomp_syscall_resolve_name*(name: cstring): cint
+proc seccomp_syscall_resolve_name_rewrite*(name: cstring): cint
+proc seccomp_rule_add*(ctx: scmp_filter_ctx; action: uint32; syscall: cint;
+  arg_cnt: cuint): cint {.varargs.}
+proc seccomp_load*(ctx: scmp_filter_ctx): cint
+proc seccomp_release*(ctx: scmp_filter_ctx)
+
+{.pop.}