about summary refs log tree commit diff stats
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/buffer.nim20
-rw-r--r--src/server/forkserver.nim33
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