diff options
author | bptato <nincsnevem662@gmail.com> | 2024-03-28 01:36:29 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-03-28 01:36:29 +0100 |
commit | b530ccc899a8cc8c63bad29abe1e479eb999b167 (patch) | |
tree | 07062947dfda3ac4356b0ce26de1cbe4e4c87ebd /src/server | |
parent | 52c415762fda7b9369ed4cf88783a6639574e3ea (diff) | |
download | chawan-b530ccc899a8cc8c63bad29abe1e479eb999b167.tar.gz |
Add capsicum support
It's the sandboxing system of FreeBSD. Quite pleasant to work with. (Just trying to figure out the basics with this one before tackling the abomination that is seccomp.) Indeed, the only non-trivial part was getting newSelector to work with Capsicum. Long story short it doesn't, so we use an ugly pointer cast + assignment. But even that is stdlib's "fault", not Capsicum's. This also gets rid of that ugly SocketPath global.
Diffstat (limited to 'src/server')
-rw-r--r-- | src/server/buffer.nim | 20 | ||||
-rw-r--r-- | src/server/forkserver.nim | 33 |
2 files changed, 40 insertions, 13 deletions
diff --git a/src/server/buffer.nim b/src/server/buffer.nim index 0df80567..12665334 100644 --- a/src/server/buffer.nim +++ b/src/server/buffer.nim @@ -904,6 +904,10 @@ const bsdPlatform = defined(macosx) or defined(freebsd) or defined(netbsd) or proc onload(buffer: Buffer) +when defined(freebsd): + # necessary for an ugly hack we will do later + import std/kqueue + # Create an exact clone of the current buffer. # This clone will share the loader process with the previous buffer. proc clone*(buffer: Buffer, newurl: URL): int {.proxy.} = @@ -932,7 +936,14 @@ proc clone*(buffer: Buffer, newurl: URL): int {.proxy.} = # Closing seems to suffice here. when not bsdPlatform: buffer.selector.close() - buffer.selector = newSelector[int]() + when defined(freebsd): + # hack necessary because newSelector calls sysctl, but capsicum really + # dislikes that. + let fd = kqueue() + doAssert fd != -1 + cast[ptr cint](buffer.selector)[] = fd + else: + buffer.selector = newSelector[int]() #TODO set buffer.window.timeouts.selector var cfds: seq[int] = @[] for fd in buffer.loader.connecting.keys: @@ -964,7 +975,8 @@ proc clone*(buffer: Buffer, newurl: URL): int {.proxy.} = # We ignore errors; not much we can do with them here :/ discard buffer.rewind(buffer.bytesRead, unregister = false) buffer.pstream.sclose() - let ssock = initServerSocket(myPid) + let ssock = initServerSocket(buffer.loader.sockDir, buffer.loader.sockDirFd, + myPid) buffer.ssock = ssock ps.write(char(0)) buffer.url = newurl @@ -1866,7 +1878,7 @@ proc cleanup(buffer: Buffer) = proc launchBuffer*(config: BufferConfig; url: URL; request: Request; attrs: WindowAttributes; ishtml: bool; charsetStack: seq[Charset]; - loader: FileLoader; ssock: ServerSocket) = + loader: FileLoader; ssock: ServerSocket; selector: Selector[int]) = let pstream = ssock.acceptSocketStream() let buffer = Buffer( attrs: attrs, @@ -1878,7 +1890,7 @@ proc launchBuffer*(config: BufferConfig; url: URL; request: Request; pstream: pstream, request: request, rfd: pstream.fd, - selector: newSelector[int](), + selector: selector, ssock: ssock, url: url, charsetStack: charsetStack, diff --git a/src/server/forkserver.nim b/src/server/forkserver.nim index 0e1f1d3b..c1bbdedb 100644 --- a/src/server/forkserver.nim +++ b/src/server/forkserver.nim @@ -1,6 +1,7 @@ import std/options import std/os import std/posix +import std/selectors import std/tables import config/config @@ -16,6 +17,7 @@ import types/urimethodmap import types/url import types/winattrs import utils/proctitle +import utils/sandbox import utils/strwidth import chagashi/charset @@ -34,15 +36,17 @@ type ostream: PosixStream children: seq[int] loaderPid: int + sockDirFd: int + sockDir: string -proc newFileLoader*(forkserver: ForkServer; config: LoaderConfig): FileLoader = +proc forkLoader*(forkserver: ForkServer; config: LoaderConfig): int = forkserver.ostream.withPacketWriter w: w.swrite(fcForkLoader) w.swrite(config) var r = forkserver.istream.initPacketReader() var process: int r.sread(process) - return FileLoader(process: process, clientPid: getCurrentProcessId()) + return process proc loadForkServerConfig*(forkserver: ForkServer, config: Config) = forkserver.ostream.withPacketWriter w: @@ -137,10 +141,18 @@ proc forkBuffer(ctx: var ForkServerContext; r: var BufferedReader): int = for i in 0 ..< ctx.children.len: ctx.children[i] = 0 ctx.children.setLen(0) let loaderPid = ctx.loaderPid + let sockDir = ctx.sockDir + let sockDirFd = ctx.sockDirFd zeroMem(addr ctx, sizeof(ctx)) discard close(pipefd[0]) # close read + closeStdin() + closeStdout() + # must call before entering the sandbox, or capsicum cries because of Nim + # calling sysctl + let selector = newSelector[int]() + enterSandbox() let pid = getCurrentProcessId() - let ssock = initServerSocket(pid) + let ssock = initServerSocket(sockDir, sockDirFd, pid) gssock = ssock onSignal SIGTERM: # This will be overridden after buffer has been set up; it is only @@ -150,16 +162,16 @@ proc forkBuffer(ctx: var ForkServerContext; r: var BufferedReader): int = let ps = newPosixStream(pipefd[1]) ps.write(char(0)) ps.sclose() - closeStdin() - closeStdout() let loader = FileLoader( process: loaderPid, - clientPid: pid + clientPid: pid, + sockDir: sockDir, + sockDirFd: sockDirFd ) try: setBufferProcessTitle(url) launchBuffer(config, url, request, attrs, ishtml, charsetStack, loader, - ssock) + ssock, selector) except CatchableError: let e = getCurrentException() # taken from system/excpt.nim @@ -180,7 +192,8 @@ proc runForkServer() = setProcessTitle("cha forkserver") var ctx = ForkServerContext( istream: newPosixStream(stdin.getFileHandle()), - ostream: newPosixStream(stdout.getFileHandle()) + ostream: newPosixStream(stdout.getFileHandle()), + sockDirFd: -1 ) signal(SIGCHLD, SIG_IGN) while true: @@ -212,7 +225,9 @@ proc runForkServer() = var config: ForkServerConfig r.sread(config) set_cjk_ambiguous(config.ambiguous_double) - SocketDirectory = config.tmpdir + ctx.sockDir = config.tmpdir + when defined(freebsd): + ctx.sockDirFd = open(cstring(ctx.sockDir), O_DIRECTORY) except EOFError: # EOF break |