SCM_RIGHTS Transfers File-Descriptor Authority Across Unix Sockets
A privileged service can open a file that another process could not open by pathname, then pass that access through a Unix-domain socket. The receiving process gets a new file descriptor referring to the same kernel open-file state. No second pathname lookup is required, and the receiver’s ability to open that path is not re-evaluated as part of the transfer.
That property makes SCM_RIGHTS more than an IPC convenience. It moves an already-established kernel capability across a process boundary. Security therefore depends on both sides of the exchange: the sender must constrain which descriptors can leave its authority domain, and the receiver must treat incoming descriptors as privileged objects whose properties require validation.
The transfer carries an open reference, not a pathname
On Linux, ancillary data sent with sendmsg() can use SOL_SOCKET and SCM_RIGHTS to carry file descriptors over a Unix-domain socket. The receiver obtains them through recvmsg() control messages.
The kernel does not serialize the descriptor number itself as durable identity. Descriptor numbers are process-local table indexes. Instead, the operation passes a reference to the underlying open file description, and the receiver gets a descriptor number allocated in its own descriptor table.
This distinction has direct security consequences. Opening /srv/private/report normally involves pathname resolution and permission checks relevant to the opening process. Receiving a descriptor for an already-open file does not repeat that open operation. The authority embodied by the open reference has already been established.
The same pattern applies beyond regular files. File descriptors can represent sockets, pipes, event objects, directories, device nodes, and other kernel objects supported by the descriptor interface. A broker that passes descriptors is therefore delegating access to kernel objects, not merely sharing filenames.
Shared open-file state can cross the process boundary
Descriptors received through SCM_RIGHTS refer to the same open file description as the descriptor supplied by the sender. For regular files, that can include shared file offset and file status flags associated with the open file description.
This is different from two processes independently opening the same pathname. Independent opens normally create distinct open file descriptions even when they ultimately reference the same inode. Descriptor passing preserves the existing open-file relationship.
A receiver that assumes it owns an independent offset can consequently interfere with another user of the same open file description. Likewise, changing a file status flag through one descriptor can affect operations through another descriptor tied to that description. Descriptor flags such as close-on-exec are a separate per-descriptor property.
The security boundary is therefore partly about state aliasing. Delegation may grant access to an object whose mutable open-file state is also visible elsewhere.
Socket access controls who can request delegation
A descriptor broker commonly exposes a Unix-domain socket and decides which objects to open on behalf of clients. The socket endpoint becomes an authorization boundary because a successful connection can lead to authority that the client could not acquire directly.
Filesystem permissions on pathname Unix sockets can restrict connection access on Linux, but authorization often needs stronger identity binding than socket reachability alone. Linux supports peer credential mechanisms for Unix sockets, including SO_PEERCRED for connected peers and credential ancillary data when configured for that purpose.
Those credentials identify a peer according to documented kernel semantics; they do not automatically establish application-level entitlement. A broker still needs a policy mapping the authenticated process identity or service identity to the specific descriptor being requested.
Passing a descriptor after checking only that a client can connect can collapse a fine-grained resource policy into a coarse socket-access policy. That may be intentional for a tightly confined service group, but it is a deployment decision rather than a property supplied by SCM_RIGHTS.
Receivers also need a descriptor acceptance policy
The receiving side has its own trust problem. An incoming descriptor is not self-describing application data. Its integer value says nothing about the object type, access mode, origin, or suitability for the operation the receiver plans to perform.
A protocol that expects a regular file can inspect descriptor metadata before use and reject object types outside that contract. Applications may also need to verify access mode, expected filesystem properties, or other invariants relevant to the operation. The exact checks depend on the object class and threat model.
This matters when a less-trusted process can send descriptors to a more-privileged service. Accepting an unexpected directory, device, socket, or other object can redirect later operations into a kernel interface the service did not intend to expose through that IPC path.
Validation should focus on properties of the received object rather than reconstructing trust from a claimed pathname sent beside it. A pathname in the message is ordinary peer-controlled data and may not identify the object referenced by the descriptor.
Close-on-exec is part of containment
A received descriptor can outlive the IPC transaction and can also cross a later execve() unless close-on-exec is set. Linux provides MSG_CMSG_CLOEXEC for recvmsg(), which applies the close-on-exec flag to file descriptors received through SCM_RIGHTS.
Setting the flag atomically during receipt avoids a window in multithreaded programs where another thread could execute a new program between descriptor receipt and a separate fcntl() call that sets FD_CLOEXEC.
This does not reduce the receiver’s current authority over the descriptor. It limits accidental propagation into a subsequently executed program. Services that receive delegated descriptors should make inheritance policy explicit rather than relying on a later cleanup step.
Ancillary-data parsing is part of the boundary
SCM_RIGHTS arrives in the control-data area of recvmsg(). The receiver supplies a finite buffer for ancillary data, and robust code has to account for truncation and message structure rather than assuming the expected control message always arrives intact.
On Linux, excess file descriptors can be closed by the kernel when ancillary data is truncated because the receiving buffer is too small. Even with that behavior, application logic still needs to reject malformed or incomplete protocol state instead of continuing with a partial set of descriptors.
The protocol should define the expected descriptor count and the relationship between descriptors and ordinary message payload. Ambiguity here can turn a transport detail into an authorization error: a service may validate one object while later code consumes another if descriptor ordering or count is not treated as part of the message contract.
Resource limits also matter. Linux limits the number of file descriptors that may be carried in one SCM_RIGHTS control message, and process descriptor limits constrain receipt. Applications should treat transfer failure as a normal operational condition rather than assuming delegation always succeeds after authorization.
Delegation narrows pathname exposure but expands IPC authority
Descriptor passing can strengthen an architecture when a small broker owns pathname access and less-privileged workers receive only the objects needed for a task. Workers do not need broad directory permissions or credentials merely to reopen resources the broker has selected.
The same design also concentrates authority in the broker and its IPC policy. A confused-deputy flaw in resource selection can hand a valid descriptor to the wrong peer, bypassing filesystem checks that would have blocked a direct open. The kernel is enforcing the descriptor semantics correctly; the failure lies in delegating the wrong established authority.
A sound design therefore treats SCM_RIGHTS as capability transfer. The sender authorizes the exact object and recipient, the receiver validates the object class and protocol invariants, ancillary data is parsed defensively, and descriptor inheritance is constrained. Under those conditions, Unix-domain descriptor passing can reduce ambient filesystem access without pretending that the delegated authority disappeared.