Re: [RFC PATCH] af_unix: introduce MSG_CMSG_SEALED

From: Ondrej Mosnáček

Date: Mon Nov 02 2026 - 08:16:15 EST


On Mon, 2 Nov 2026 at 14:05, Ondrej Mosnáček <omosnacek@xxxxxxxxx> wrote:
>
> Currently, when a process receives a file through AF_UNIX's SCM_RIGHTS
> mechanism, the security_file_receive() LSM hook is calledto allow LSMs
> like SELinux to validate the receiver's access to the received file
> (similarly to a process inheriting file descriptors through execve(2)).
>
> However, there are cases (such as dbus daemon/dbus-broker) where the
> receiver doesn't intend to access the received file and merely wants to
> forward it to a third process. In this case the forwarding process would
> need to have the appropriate r/w access to the file in order to receive
> it, even though it will never actually acess it. That leads to the
> security policy having to grant the forwarder access to a potentially
> wide range of files (in case of dbus-broker basically all files), which
> is not ideal.
>
> This patch adds a new CMSG flag MSG_CMSG_SEALED that, when passed to
> recvmsg(2), wraps any received files into an opaque anonymous inode with
> the name "[envelope]", skipping the security_file_receive() LSM check.
> The returned "[envelope]" file descriptor can't be used in any
> meaningful way other than being passed forward via sendmsg(2) with the
> MSG_CMSG_SEALED flag. In that case the original file is unwrapped and
> sent via SCM_RIGHTS to the receiver. The receiver can then either
> receive the file as normal (subject to the LSM check) or again "sealed"
> in the "[envelope]" anon inode for further forwarding.
>
> Note that sending the "[envelope]" file is only allowed with the
> MSG_CMSG_SEALED flag set, to make the unsealing explicit and avoid
> unexpected behavior. Attempting to send it without this flag will fail
> with an error. This also avoids recursive nesting of "[envelope]" files,
> which would only make this feature harder to audit for possible issues.
>
> This patch also adds a simple read-only sockopt for UNIX sockets that
> allows userspace to determine if this feature is present (passing
> unknown CMSG flags unfortunately doesn't lead to an error currently).
> The minimal code to do so can look like this:
>
> #ifndef SO_RIGHTS_SEALED_SUPPORTED
> #define SO_RIGHTS_SEALED_SUPPORTED 88
> #endif
>
> #include <sys/socket.h>
> #include <unistd.h>
> #include <stdbool.h>
>
> bool MSG_CMSG_SEALED_supported(void)
> {
> int sock, ret;
> socklen_t optlen = 0;
>
> sock = socket(AF_UNIX, SOCK_STREAM, 0);
> if (sock < 0) {
> /* handle error */
> /* ... */
> }
>
> ret = getsockopt(sock, SOL_SOCKET, SO_RIGHTS_SEALED_SUPPORTED,
> NULL, &optlen);
> close(sock);
>
> return ret == 0;
> }
>
> Related: https://github.com/fedora-selinux/selinux-policy/issues/3286
> Related: https://github.com/fedora-selinux/selinux-policy/issues/3287
> Signed-off-by: Ondrej Mosnáček <omosnacek@xxxxxxxxx>
> ---
> arch/alpha/include/uapi/asm/socket.h | 2 +
> arch/mips/include/uapi/asm/socket.h | 2 +
> arch/parisc/include/uapi/asm/socket.h | 2 +
> arch/sparc/include/uapi/asm/socket.h | 2 +
> include/linux/socket.h | 4 +-
> include/net/scm.h | 2 +-
> include/uapi/asm-generic/socket.h | 2 +
> io_uring/net.c | 2 +-
> net/compat.c | 3 +-
> net/core/scm.c | 81 +++++++++++++++++++++----
> net/core/sock.c | 9 +++
> net/socket.c | 2 +-
> tools/include/uapi/asm-generic/socket.h | 2 +
> 13 files changed, 97 insertions(+), 18 deletions(-)

See also this RFC patch for selinux-testsuite
(https://github.com/SELinuxProject/selinux-testsuite) that I used to
test this patch:
https://lore.kernel.org/selinux/20261102130834.253605-1-omosnacek@xxxxxxxxx/