diff options
author | bptato <nincsnevem662@gmail.com> | 2024-07-24 19:45:52 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-07-24 19:46:49 +0200 |
commit | de2a70dc814658a8c72e7da6180ea5e16a8b985b (patch) | |
tree | c089a85e65d0069e2d51b12d1553ada8c2a63ea6 /src/utils | |
parent | 40122721d3b25d3b7e75f93e64d88853d1c9c0f2 (diff) | |
download | chawan-de2a70dc814658a8c72e7da6180ea5e16a8b985b.tar.gz |
client, sandbox: fix termux build
Still not perfect, because it crashes on missing /tmp dir so you have to manually set it...
Diffstat (limited to 'src/utils')
-rw-r--r-- | src/utils/sandbox.nim | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/src/utils/sandbox.nim b/src/utils/sandbox.nim index efc03e49..19e6fd0a 100644 --- a/src/utils/sandbox.nim +++ b/src/utils/sandbox.nim @@ -81,6 +81,53 @@ elif SandboxMode == stLibSeccomp: import std/posix import bindings/libseccomp + when defined(android): + let PR_SET_VMA {.importc, header: "<sys/prctl.h>", nodecl.}: cint + let PR_SET_VMA_ANON_NAME {.importc, header: "<sys/prctl.h>", nodecl.}: cint + + proc allowBionic(ctx: scmp_filter_ctx) = + # Things needed for bionic libc. Tested with Termux. + const androidAllowList = [ + cstring"rt_sigprocmask", + "epoll_pwait", + "futex", + "madvise" + ] + for it in androidAllowList: + let syscall = seccomp_syscall_resolve_name(it) + doAssert seccomp_rule_add(ctx, SCMP_ACT_ALLOW, syscall, 0) == 0 + # bionic likes to set this very much. In fact, it was added to + # the kernel by Android devs. + block allowAnonVMAName: + let syscall = seccomp_syscall_resolve_name("prctl") + let arg0 = scmp_arg_cmp( + arg: 0, # op + op: SCMP_CMP_EQ, # equals + datum_a: uint64(PR_SET_VMA) + ) + let arg1 = scmp_arg_cmp( + arg: 1, # attr + op: SCMP_CMP_EQ, # equals + datum_a: uint64(PR_SET_VMA_ANON_NAME) + ) + doAssert seccomp_rule_add(ctx, SCMP_ACT_ALLOW, syscall, 2, arg0, + arg1) == 0 + # We have to be careful with this one; PROT_EXEC will happily set + # memory as executable, which is certainly not what we want. + # Now, bionic seems to be calling this from mutate(), ergo we + # should be fine just allowing PROT_READ and PROT_READ | PROT_WRITE. + block allowMprotect: + let syscall = seccomp_syscall_resolve_name("mprotect") + let arg2 = scmp_arg_cmp( + arg: 2, # attr + op: SCMP_CMP_LE, # less or equals + datum_a: 3 # PROT_READ | PROT_WRITE + ) + # Note that libseccomp can't really express multiple comparisons. + # However, we are lucky, and we only have to "excessively" allow + # PROT_WRITE (w/o PROT_READ) and PROT_NONE, which does no harm. + doAssert seccomp_rule_add(ctx, SCMP_ACT_ALLOW, syscall, 1, arg2) == 0 + proc enterBufferSandbox*(sockPath: string) = onSignal SIGSYS: discard sig @@ -137,6 +184,8 @@ elif SandboxMode == stLibSeccomp: datum_a: 1 # PF_LOCAL == PF_UNIX == AF_UNIX ) doAssert seccomp_rule_add(ctx, SCMP_ACT_ALLOW, syscall, 1, arg0) == 0 + when defined(android): + ctx.allowBionic() doAssert seccomp_load(ctx) == 0 seccomp_release(ctx) @@ -155,9 +204,6 @@ elif SandboxMode == stLibSeccomp: "poll", # curl needs poll "getpid", # used indirectly by OpenSSL EVP_RAND_CTX_new (through drbg) "fstat", # glibc fread seems to call it - # maybe it will need epoll too in the future - "epoll_create", "epoll_create1", "epoll_ctl", "epoll_wait", - "ppoll", # or ppoll # we either have to use CURLOPT_NOSIGNAL or allow signals. # do the latter, otherwise the default name resolver will never time out. "signal", "sigaction", "rt_sigaction", @@ -165,6 +211,8 @@ elif SandboxMode == stLibSeccomp: for it in allowList: doAssert seccomp_rule_add(ctx, SCMP_ACT_ALLOW, seccomp_syscall_resolve_name(it), 0) == 0 + when defined(android): + ctx.allowBionic() doAssert seccomp_load(ctx) == 0 seccomp_release(ctx) else: |