diff options
author | bptato <nincsnevem662@gmail.com> | 2024-04-18 18:30:53 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-04-18 18:30:53 +0200 |
commit | 38db6ab5be80b255fe40df715adc3b5852875cdd (patch) | |
tree | 328eada3b571e475903be0df61c5abf09c022d8b /src/io/serversocket.nim | |
parent | 5bb9542045ff6dbb6c357eb4dd0a7616dba33a9a (diff) | |
download | chawan-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/io/serversocket.nim')
-rw-r--r-- | src/io/serversocket.nim | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/src/io/serversocket.nim b/src/io/serversocket.nim index ea5bc97d..dff6de70 100644 --- a/src/io/serversocket.nim +++ b/src/io/serversocket.nim @@ -5,9 +5,10 @@ import std/os when defined(posix): import std/posix -type ServerSocket* = object +type ServerSocket* = ref object sock*: Socket path*: string + dfd: int const SocketPathPrefix = "cha_sock_" proc getSocketName*(pid: int): string = @@ -29,6 +30,13 @@ when defined(freebsd): proc bindat_unix_from_c(dfd, sock: cint; path: cstring; pathlen: cint): cint {.importc.} +proc initServerSocket*(fd: SocketHandle; sockDir: string; pid, sockDirFd: int): + ServerSocket = + let sock = newSocket(fd, Domain.AF_UNIX, SockType.SOCK_STREAM, + Protocol.IPPROTO_IP, buffered = false) + let path = getSocketPath(sockDir, pid) + return ServerSocket(sock: sock, path: path, dfd: sockDirFd) + proc initServerSocket*(sockDir: string; sockDirFd, pid: int; blocking = true): ServerSocket = let sock = newSocket(Domain.AF_UNIX, SockType.SOCK_STREAM, @@ -37,7 +45,7 @@ proc initServerSocket*(sockDir: string; sockDirFd, pid: int; blocking = true): sock.getFd().setBlocking(false) let path = getSocketPath(sockDir, pid) if sockDirFd == -1: - discard unlink(cstring(path)) + discard tryRemoveFile(path) if bind_unix_from_c(cint(sock.getFd()), cstring(path), cint(path.len)) != 0: raiseOSError(osLastError()) else: @@ -47,9 +55,17 @@ proc initServerSocket*(sockDir: string; sockDirFd, pid: int; blocking = true): if bindat_unix_from_c(cint(sockDirFd), cint(sock.getFd()), cstring(name), cint(name.len)) != 0: raiseOSError(osLastError()) + else: + # shouldn't have sockDirFd on other architectures + doAssert false listen(sock) - return ServerSocket(sock: sock, path: path) + return ServerSocket(sock: sock, path: path, dfd: sockDirFd) -proc close*(ssock: ServerSocket) = +proc close*(ssock: ServerSocket; unlink = true) = close(ssock.sock) - discard unlink(cstring(ssock.path)) + if unlink: + when defined(freebsd): + if ssock.dfd != -1: + discard unlinkat(cint(ssock.dfd), cstring(ssock.path), 0) + return + discard tryRemoveFile(ssock.path) |