[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CAAVpQUCLoYa8YbaPSMHJcFQarz9hMo6-BQ1OJiF+GwcF5bb6hQ@mail.gmail.com>
Date: Thu, 31 Jul 2025 16:37:49 -0700
From: Kuniyuki Iwashima <kuniyu@...gle.com>
To: demiobenour@...il.com
Cc: "David S. Miller" <davem@...emloft.net>, Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>, Paolo Abeni <pabeni@...hat.com>, Simon Horman <horms@...nel.org>,
netdev@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH RFC net] af_unix: allow disabling connections to abstract sockets
On Thu, Jul 31, 2025 at 4:03 PM Demi Marie Obenour via B4 Relay
<devnull+demiobenour.gmail.com@...nel.org> wrote:
>
> From: Demi Marie Obenour <demiobenour@...il.com>
>
> Abstract sockets have been a security risk in the past. Since they
> aren't associated with filesystem paths, they bypass all filesystem
> access controls. This means that they can allow file descriptors to be
> passed out of sandboxes that do not allow connecting to named sockets.
I just thought that what's you need is unshare(CLONE_NEWNET)
and started reading this...
https://labs.snyk.io/resources/nixos-deep-dive/
and stopped reading here.
---8<---
Nix builds offer a second, slightly less restrictive type of sandbox
for use in ‘Fixed output derivations’. These build types are expected
to retrieve files from the internet (for example, cloning a git repository
for later building); as such, they are not isolated in a network namespace
and are instead in the main network namespace ...
---8<---
The 2nd thought is you just need CLONE_NEWNET and proper
setup to connect two netns.
> On systems using the Nix daemon, this allowed privilege escalation to
> root, and fixing the bug required Nix to use a complete user-mode
> network stack. Furthermore, anyone can bind to any abstract socket
> path, so anyone connecting to an abstract socket has no idea who they
> are connecting to.
>
> This allows disabling the security hole by preventing all connections to
> abstract sockets. For compatibility, it is still possible to bind to
> abstract socket paths, but such sockets will never receive any
> connections or datagrams.
>
> Signed-off-by: Demi Marie Obenour <demiobenour@...il.com>
> ---
> net/unix/Kconfig | 12 ++++++++++++
> net/unix/af_unix.c | 18 +++++++++++++-----
> 2 files changed, 25 insertions(+), 5 deletions(-)
>
> diff --git a/net/unix/Kconfig b/net/unix/Kconfig
> index 6f1783c1659b81c3c3c89cb7634a9ce780144f26..c34f222f21b097ce4a735ce02d8ce11fc71bde19 100644
> --- a/net/unix/Kconfig
> +++ b/net/unix/Kconfig
> @@ -16,6 +16,18 @@ config UNIX
>
> Say Y unless you know what you are doing.
>
> +config UNIX_ABSTRACT
> + bool "UNIX: abstract sockets"
> + depends on UNIX
> + default y
> + help
> + Support for "abstract" sockets (those not bound to a path).
> + These have been used in the past, but they can also represent
> + a security risk because anyone can bind to any abstract
> + socket. If you disable this option, programs can still bind
> + to abstract sockets, but any attempt to connect to one fails
> + with -ECONNREFUSED.
> +
> config AF_UNIX_OOB
> bool "UNIX: out-of-bound messages"
> depends on UNIX
> diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
> index 52b155123985a18632fc12dc986150e38f2fee70..81d55849dac58e4e68c28ed03a9bc978777cfe4f 100644
> --- a/net/unix/af_unix.c
> +++ b/net/unix/af_unix.c
> @@ -332,7 +332,8 @@ static inline void unix_release_addr(struct unix_address *addr)
> * - if started by zero, it is abstract name.
> */
>
> -static int unix_validate_addr(struct sockaddr_un *sunaddr, int addr_len)
> +static int unix_validate_addr(struct sockaddr_un *sunaddr, int addr_len,
> + bool bind)
> {
> if (addr_len <= offsetof(struct sockaddr_un, sun_path) ||
> addr_len > sizeof(*sunaddr))
> @@ -341,6 +342,9 @@ static int unix_validate_addr(struct sockaddr_un *sunaddr, int addr_len)
> if (sunaddr->sun_family != AF_UNIX)
> return -EINVAL;
>
> + if (!bind && !IS_ENABLED(CONFIG_UNIX_ABSTRACT) && !sunaddr->sun_path[0])
> + return -ECONNREFUSED; /* pretend nobody is listening */
> +
> return 0;
> }
>
> @@ -1253,6 +1257,8 @@ static struct sock *unix_find_other(struct net *net,
>
> if (sunaddr->sun_path[0])
> sk = unix_find_bsd(sunaddr, addr_len, type, flags);
> + else if (!IS_ENABLED(CONFIG_UNIX_ABSTRACT))
> + sk = ERR_PTR(-EPERM);
> else
> sk = unix_find_abstract(net, sunaddr, addr_len, type);
>
> @@ -1444,7 +1450,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
> sunaddr->sun_family == AF_UNIX)
> return unix_autobind(sk);
>
> - err = unix_validate_addr(sunaddr, addr_len);
> + err = unix_validate_addr(sunaddr, addr_len, true);
> if (err)
> return err;
>
> @@ -1493,7 +1499,7 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
> goto out;
>
> if (addr->sa_family != AF_UNSPEC) {
> - err = unix_validate_addr(sunaddr, alen);
> + err = unix_validate_addr(sunaddr, alen, false);
> if (err)
> goto out;
>
> @@ -1612,7 +1618,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
> long timeo;
> int err;
>
> - err = unix_validate_addr(sunaddr, addr_len);
> + err = unix_validate_addr(sunaddr, addr_len, false);
> if (err)
> goto out;
>
> @@ -2048,7 +2054,9 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
> }
>
> if (msg->msg_namelen) {
> - err = unix_validate_addr(msg->msg_name, msg->msg_namelen);
> + err = unix_validate_addr(msg->msg_name,
> + msg->msg_namelen,
> + false);
> if (err)
> goto out;
>
>
> ---
> base-commit: 038d61fd642278bab63ee8ef722c50d10ab01e8f
> change-id: 20250731-no-abstract-6672e8ad03e1
>
> Best regards,
> --
> Demi Marie Obenour <demiobenour@...il.com>
>
>
Powered by blists - more mailing lists