Unix Domain Socket, Network Framework and App Sandboxing

Dear Apple Developers,

I am working on a macOS project where the container app acts as a server and communicates with a command-line program developed by my colleagues via a Unix domain socket.

The macOS part was written using the new Network Framework. Here is a snippet of the code:

let params = NWParameters()
let socketFile = URL(fileURLWithPath: socketPath)
params.defaultProtocolStack.transportProtocol = NWProtocolTCP.Options()
params.requiredLocalEndpoint = NWEndpoint.unix(path: socketFile.path)
params.allowLocalEndpointReuse = true

self.listener = try! NWListener(using: params)

listener?.newConnectionHandler = ...
listener?.start()

When my colleague's program needs to send data, it connects to the socket created by the macOS app, and the data is received perfectly—unless the macOS app is sandboxed.

I have added outgoing and incoming connections entitlements to the macOS app. I tested my colleague's program both embedded in the macOS app and separately, ensuring to add the com.apple.security.inherit entitlement as well. However, it still doesn't work when the macOS app is sandboxed.

The socket file's permission is srwxr-xr-x@ and is located in the containers folder when sandboxed, and srwxr-xr-x and HOME/Library/Application Support/MyApp when not sandboxed.

What could be going wrong? Does the Network Framework support this use case, or do I need to revert to using AF_UNIX?

Thank you for your assistance.

Best regards.

ps.

My colleagues' program was written in go, using a standard function conn, err := net.Dial("unix", "socket_path_in_container"). It outputs invalid argument error when the macOS App is sandboxed.

Answered by neil218 in 790320022

Dear Apple Developers,

I apologize for the confusion earlier. I've managed to resolve my issue.

It turns out Unix domain socket's path must not exceed 108 characters. With Sandboxing enabled, the home container path became very long.

Thank you for your support.

Best regards.

Accepted Answer

Dear Apple Developers,

I apologize for the confusion earlier. I've managed to resolve my issue.

It turns out Unix domain socket's path must not exceed 108 characters. With Sandboxing enabled, the home container path became very long.

Thank you for your support.

Best regards.

Yeah, Unix domain sockets are tricky. The ultimate limit is 253 bytes, which is SOCK_MAXADDRLEN minus the two byte header containing sun_family and sun_len. However, sockaddr_un is defined such that sun_path is 104. This artificially limits the length. Network framework inherits that artificial limit.

I’m pretty sure I filed a bug against Network framework about that… but where did I put it… OK, I did (r. 125081070).

The best path forward depends on your constraints:

  • You’re able to use a shorter length, do that and stick with Network framework.

  • If not, you have to use BSD Sockets directly )-:

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Unix Domain Socket, Network Framework and App Sandboxing
 
 
Q