As many of you know sydbox can do network sandboxing but for some reasons we didn’t have it on by default on Exherbo.

For those who don’t know much about sydbox and network sandboxing let me explain it briefly. Network sandboxing has three modes:

  • allow: All network connections are allowed.
  • local: Only local network connections are allowed.
  • deny: No network connections are allowed.

In addition to that there’s a restrict_connect option which disallows connects to all addresses except addresses that one of the parents has bind()‘ed to.

There’s also a network white list which specifies the additional network addresses that are allowed in local and deny modes.

On Exherbo we use the mode local with restrict_connect option enabled.

One limitation of sydbox was it couldn’t white list bind() addresses whose port were zero. The reason is obvious. The only place we can look up the actual port is /proc/net/tcp, or /proc/net/tcp6 for ipv6, and we need to do this before the bind() call has completed. The problem arises here. The /proc/net/tcp entry is only created after the bind() call has succeeded.

The solution isn’t entirely trivial. We have to note the file descriptor argument of bind() along with the socket family and socket address and intercept the subsequent listen() call. Only then we can look up the port argument from /proc/net/tcp.

The sydbox master has a simple implementation to solve this problem. If the port argument of a bind() call is zero, we save the file descriptor and the corresponding socket family and address to a GHashTable. After that the subsequent listen() call is intercepted and if the file descriptor of the listen() call matches a file descriptor in the hash table, sydbox looks up the port from /proc/net/tcp, fills it in and white lists the address.

With sydbox-0.4, which I’ll release after some testing, network sandboxing will be on by default again for the Paludis profile.

Just to be on the secure side ;)