Netdev List
 help / color / mirror / Atom feed
* [PATCH net] net: devmem: check uid and netns in net_devmem_get_binding()
@ 2026-10-05 21:04 Kaifeng Wang
  2026-10-05 21:09 ` netdev-bot+sinfo
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Kaifeng Wang @ 2026-10-05 21:04 UTC (permalink / raw)
  To: netdev
  Cc: almasrymina, edumazet, pabeni, willemb, davem, kuba, horms, sdf,
	bobbyeshleman, kaiyuanz, linux-kernel, Kaifeng Wang

NETDEV_CMD_BIND_TX is unprivileged, and dmabuf binding IDs are allocated
from a single global xarray. Currently net_devmem_get_binding() looks up
the binding by ID without checking whether the sending socket belongs to
the same user or network namespace that created the binding.

Record the creating netlink socket's network namespace and UID on the
binding, and verify both in net_devmem_get_binding() before checking the
route destination device. Return -EINVAL on mismatch so callers cannot
distinguish non-existent IDs from bindings owned by other users.

Fixes: bd61848900bf ("net: devmem: Implement TX path")
Signed-off-by: Kaifeng Wang <kaifengw@google.com>
---
 net/core/devmem.c      | 7 ++++++-
 net/core/devmem.h      | 5 +++++
 net/core/netdev-genl.c | 5 +++--
 3 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/net/core/devmem.c b/net/core/devmem.c
index f4d60654ce7f..9a773b1ce92d 100644
--- a/net/core/devmem.c
+++ b/net/core/devmem.c
@@ -191,6 +191,7 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
 		       enum dma_data_direction direction,
 		       unsigned int dmabuf_fd, unsigned int niov_shift,
 		       struct netdev_nl_sock *priv,
+		       const struct sock *nl_sk,
 		       struct netlink_ext_ack *extack)
 {
 	struct net_devmem_dmabuf_binding *binding;
@@ -220,6 +221,8 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
 
 	binding->dev = dev;
 	binding->vdev = vdev;
+	write_pnet(&binding->net, sock_net(nl_sk));
+	binding->uid = sk_uid(nl_sk);
 	binding->niov_shift = niov_shift;
 	xa_init_flags(&binding->bound_rxqs, XA_FLAGS_ALLOC);
 
@@ -390,7 +393,9 @@ struct net_devmem_dmabuf_binding *net_devmem_get_binding(struct sock *sk,
 	int err = 0;
 
 	binding = net_devmem_lookup_dmabuf(dmabuf_id);
-	if (!binding || !binding->tx_vec) {
+	if (!binding || !binding->tx_vec ||
+	    !net_eq(sock_net(sk), read_pnet(&binding->net)) ||
+	    !uid_eq(sk_uid(sk), binding->uid)) {
 		err = -EINVAL;
 		goto out_err;
 	}
diff --git a/net/core/devmem.h b/net/core/devmem.h
index 4a293a7d1149..7b9d3e04367c 100644
--- a/net/core/devmem.h
+++ b/net/core/devmem.h
@@ -10,6 +10,7 @@
 #ifndef _NET_DEVMEM_H
 #define _NET_DEVMEM_H
 
+#include <net/net_namespace.h>
 #include <net/netmem.h>
 #include <net/netdev_netlink.h>
 
@@ -26,6 +27,8 @@ struct net_devmem_dmabuf_binding {
 	 * dereferenced.
 	 */
 	void *vdev;
+	possible_net_t net;
+	kuid_t uid;
 	struct gen_pool *chunk_pool;
 	/* Protect dev */
 	struct mutex lock;
@@ -97,6 +100,7 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
 		       enum dma_data_direction direction,
 		       unsigned int dmabuf_fd, unsigned int niov_shift,
 		       struct netdev_nl_sock *priv,
+		       const struct sock *nl_sk,
 		       struct netlink_ext_ack *extack);
 struct net_devmem_dmabuf_binding *net_devmem_lookup_dmabuf(u32 id);
 void net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding);
@@ -181,6 +185,7 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
 		       unsigned int dmabuf_fd,
 		       unsigned int niov_shift,
 		       struct netdev_nl_sock *priv,
+		       const struct sock *nl_sk,
 		       struct netlink_ext_ack *extack)
 {
 	return ERR_PTR(-EOPNOTSUPP);
diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
index 33b9f4eb9565..847814e3df3f 100644
--- a/net/core/netdev-genl.c
+++ b/net/core/netdev-genl.c
@@ -1094,7 +1094,7 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
 
 	binding = net_devmem_bind_dmabuf(netdev, NULL, dma_dev, DMA_FROM_DEVICE,
 					 dmabuf_fd, niov_shift, priv,
-					 info->extack);
+					 NETLINK_CB(skb).sk, info->extack);
 	if (IS_ERR(binding)) {
 		err = PTR_ERR(binding);
 		goto err_rxq_bitmap;
@@ -1243,7 +1243,8 @@ int netdev_nl_bind_tx_doit(struct sk_buff *skb, struct genl_info *info)
 	binding = net_devmem_bind_dmabuf(bind_dev,
 					 bind_dev != netdev ? netdev : NULL,
 					 dma_dev, DMA_TO_DEVICE, dmabuf_fd,
-					 PAGE_SHIFT, priv, info->extack);
+					 PAGE_SHIFT, priv, NETLINK_CB(skb).sk,
+					 info->extack);
 	if (IS_ERR(binding)) {
 		err = PTR_ERR(binding);
 		goto err_unlock_bind_dev;
-- 
2.56.0.rc1.315.gc6ed9934b7-goog


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH net] net: devmem: check uid and netns in net_devmem_get_binding()
  2026-10-05 21:04 [PATCH net] net: devmem: check uid and netns in net_devmem_get_binding() Kaifeng Wang
@ 2026-10-05 21:09 ` netdev-bot+sinfo
  2026-10-05 21:22   ` Kaifeng Wang
  2026-10-05 22:24 ` Stanislav Fomichev
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: netdev-bot+sinfo @ 2026-10-05 21:09 UTC (permalink / raw)
  To: Kaifeng Wang
  Cc: netdev, almasrymina, edumazet, pabeni, willemb, davem, kuba,
	horms, sdf, bobbyeshleman, kaiyuanz, linux-kernel

Hi!

This is an automated message. This series looks like a fix, but its
commit messages seem to be missing some information:

 - How the issue was discovered, e.g. hit in production, hit during
   development, syzbot report, manual code inspection, LLM or static
   analysis tool scan.

 - Whether the issue was actually triggered, or is only theoretical
   (e.g. found by code inspection). If it was triggered please include
   the symptoms, like the stack trace or error messages.

Please do not repost the series just to address the above. Instead,
reply to this email with the missing information, so that reviewers
can take it into account. If the series needs another revision for
other reasons, please include the information in the commit messages
then.

The evaluation is done by an LLM so it may be wrong, if you think
that is the case please reply and explain.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH net] net: devmem: check uid and netns in net_devmem_get_binding()
  2026-10-05 21:09 ` netdev-bot+sinfo
@ 2026-10-05 21:22   ` Kaifeng Wang
  0 siblings, 0 replies; 7+ messages in thread
From: Kaifeng Wang @ 2026-10-05 21:22 UTC (permalink / raw)
  To: netdev-bot+sinfo
  Cc: netdev, almasrymina, edumazet, pabeni, willemb, davem, kuba,
	horms, sdf, bobbyeshleman, kaiyuanz, linux-kernel

This issue was found by the Sashiko code review bot on the netdev
mailing list (Message-ID:
<179007458060.2160803.1077952399417880240@kernel.org>)
We verified it locally with a test that creates a TX dmabuf binding
via NETDEV_CMD_BIND_TX and sends packets from a socket owned by a
different UID or in a different network namespace. Without this patch,
the cross-UID and cross-netns sends succeed using the victim's dmabuf
binding ID; with this patch, net_devmem_get_binding() rejects them
with -EINVAL as expected.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH net] net: devmem: check uid and netns in net_devmem_get_binding()
  2026-10-05 21:04 [PATCH net] net: devmem: check uid and netns in net_devmem_get_binding() Kaifeng Wang
  2026-10-05 21:09 ` netdev-bot+sinfo
@ 2026-10-05 22:24 ` Stanislav Fomichev
  2026-10-06 16:19 ` Bobby Eshleman
  2026-10-08  0:04 ` netdev-bot+sashiko
  3 siblings, 0 replies; 7+ messages in thread
From: Stanislav Fomichev @ 2026-10-05 22:24 UTC (permalink / raw)
  To: Kaifeng Wang
  Cc: netdev, almasrymina, edumazet, pabeni, willemb, davem, kuba,
	horms, sdf, bobbyeshleman, kaiyuanz, linux-kernel

On 10/05, Kaifeng Wang wrote:
> NETDEV_CMD_BIND_TX is unprivileged, and dmabuf binding IDs are allocated
> from a single global xarray. Currently net_devmem_get_binding() looks up
> the binding by ID without checking whether the sending socket belongs to
> the same user or network namespace that created the binding.
> 
> Record the creating netlink socket's network namespace and UID on the
> binding, and verify both in net_devmem_get_binding() before checking the
> route destination device. Return -EINVAL on mismatch so callers cannot
> distinguish non-existent IDs from bindings owned by other users.
> 
> Fixes: bd61848900bf ("net: devmem: Implement TX path")
> Signed-off-by: Kaifeng Wang <kaifengw@google.com>

Acked-by: Stanislav Fomichev <sdf@fomichev.me>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH net] net: devmem: check uid and netns in net_devmem_get_binding()
  2026-10-05 21:04 [PATCH net] net: devmem: check uid and netns in net_devmem_get_binding() Kaifeng Wang
  2026-10-05 21:09 ` netdev-bot+sinfo
  2026-10-05 22:24 ` Stanislav Fomichev
@ 2026-10-06 16:19 ` Bobby Eshleman
  2026-10-08  0:04 ` netdev-bot+sashiko
  3 siblings, 0 replies; 7+ messages in thread
From: Bobby Eshleman @ 2026-10-06 16:19 UTC (permalink / raw)
  To: Kaifeng Wang
  Cc: netdev, almasrymina, edumazet, pabeni, willemb, davem, kuba,
	horms, sdf, bobbyeshleman, kaiyuanz, linux-kernel

On Mon, Oct 05, 2026 at 09:04:03PM +0000, Kaifeng Wang wrote:
> NETDEV_CMD_BIND_TX is unprivileged, and dmabuf binding IDs are allocated
> from a single global xarray. Currently net_devmem_get_binding() looks up
> the binding by ID without checking whether the sending socket belongs to
> the same user or network namespace that created the binding.
> 
> Record the creating netlink socket's network namespace and UID on the
> binding, and verify both in net_devmem_get_binding() before checking the
> route destination device. Return -EINVAL on mismatch so callers cannot
> distinguish non-existent IDs from bindings owned by other users.
> 
> Fixes: bd61848900bf ("net: devmem: Implement TX path")
> Signed-off-by: Kaifeng Wang <kaifengw@google.com>
> ---
>  net/core/devmem.c      | 7 ++++++-
>  net/core/devmem.h      | 5 +++++
>  net/core/netdev-genl.c | 5 +++--
>  3 files changed, 14 insertions(+), 3 deletions(-)
> 
> diff --git a/net/core/devmem.c b/net/core/devmem.c
> index f4d60654ce7f..9a773b1ce92d 100644
> --- a/net/core/devmem.c
> +++ b/net/core/devmem.c
> @@ -191,6 +191,7 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
>  		       enum dma_data_direction direction,
>  		       unsigned int dmabuf_fd, unsigned int niov_shift,
>  		       struct netdev_nl_sock *priv,
> +		       const struct sock *nl_sk,
>  		       struct netlink_ext_ack *extack)
>  {
>  	struct net_devmem_dmabuf_binding *binding;
> @@ -220,6 +221,8 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
>  
>  	binding->dev = dev;
>  	binding->vdev = vdev;
> +	write_pnet(&binding->net, sock_net(nl_sk));
> +	binding->uid = sk_uid(nl_sk);
>  	binding->niov_shift = niov_shift;
>  	xa_init_flags(&binding->bound_rxqs, XA_FLAGS_ALLOC);
>  
> @@ -390,7 +393,9 @@ struct net_devmem_dmabuf_binding *net_devmem_get_binding(struct sock *sk,
>  	int err = 0;
>  
>  	binding = net_devmem_lookup_dmabuf(dmabuf_id);
> -	if (!binding || !binding->tx_vec) {
> +	if (!binding || !binding->tx_vec ||
> +	    !net_eq(sock_net(sk), read_pnet(&binding->net)) ||
> +	    !uid_eq(sk_uid(sk), binding->uid)) {
>  		err = -EINVAL;
>  		goto out_err;
>  	}
> diff --git a/net/core/devmem.h b/net/core/devmem.h
> index 4a293a7d1149..7b9d3e04367c 100644
> --- a/net/core/devmem.h
> +++ b/net/core/devmem.h
> @@ -10,6 +10,7 @@
>  #ifndef _NET_DEVMEM_H
>  #define _NET_DEVMEM_H
>  
> +#include <net/net_namespace.h>
>  #include <net/netmem.h>
>  #include <net/netdev_netlink.h>
>  
> @@ -26,6 +27,8 @@ struct net_devmem_dmabuf_binding {
>  	 * dereferenced.
>  	 */
>  	void *vdev;
> +	possible_net_t net;
> +	kuid_t uid;
>  	struct gen_pool *chunk_pool;
>  	/* Protect dev */
>  	struct mutex lock;
> @@ -97,6 +100,7 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
>  		       enum dma_data_direction direction,
>  		       unsigned int dmabuf_fd, unsigned int niov_shift,
>  		       struct netdev_nl_sock *priv,
> +		       const struct sock *nl_sk,
>  		       struct netlink_ext_ack *extack);
>  struct net_devmem_dmabuf_binding *net_devmem_lookup_dmabuf(u32 id);
>  void net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding);
> @@ -181,6 +185,7 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
>  		       unsigned int dmabuf_fd,
>  		       unsigned int niov_shift,
>  		       struct netdev_nl_sock *priv,
> +		       const struct sock *nl_sk,
>  		       struct netlink_ext_ack *extack)
>  {
>  	return ERR_PTR(-EOPNOTSUPP);
> diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
> index 33b9f4eb9565..847814e3df3f 100644
> --- a/net/core/netdev-genl.c
> +++ b/net/core/netdev-genl.c
> @@ -1094,7 +1094,7 @@ int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
>  
>  	binding = net_devmem_bind_dmabuf(netdev, NULL, dma_dev, DMA_FROM_DEVICE,
>  					 dmabuf_fd, niov_shift, priv,
> -					 info->extack);
> +					 NETLINK_CB(skb).sk, info->extack);
>  	if (IS_ERR(binding)) {
>  		err = PTR_ERR(binding);
>  		goto err_rxq_bitmap;
> @@ -1243,7 +1243,8 @@ int netdev_nl_bind_tx_doit(struct sk_buff *skb, struct genl_info *info)
>  	binding = net_devmem_bind_dmabuf(bind_dev,
>  					 bind_dev != netdev ? netdev : NULL,
>  					 dma_dev, DMA_TO_DEVICE, dmabuf_fd,
> -					 PAGE_SHIFT, priv, info->extack);
> +					 PAGE_SHIFT, priv, NETLINK_CB(skb).sk,
> +					 info->extack);
>  	if (IS_ERR(binding)) {
>  		err = PTR_ERR(binding);
>  		goto err_unlock_bind_dev;
> -- 
> 2.56.0.rc1.315.gc6ed9934b7-goog
> 

Reviewed-by: Bobby Eshleman <bobbyeshleman@meta.com>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH net] net: devmem: check uid and netns in net_devmem_get_binding()
  2026-10-05 21:04 [PATCH net] net: devmem: check uid and netns in net_devmem_get_binding() Kaifeng Wang
                   ` (2 preceding siblings ...)
  2026-10-06 16:19 ` Bobby Eshleman
@ 2026-10-08  0:04 ` netdev-bot+sashiko
  2026-10-08 21:40   ` Kaifeng Wang
  3 siblings, 1 reply; 7+ messages in thread
From: netdev-bot+sashiko @ 2026-10-08  0:04 UTC (permalink / raw)
  To: kaifengw
  Cc: netdev, almasrymina, edumazet, pabeni, willemb, davem, kuba,
	horms, sdf, bobbyeshleman, kaiyuanz, linux-kernel

Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider.

Critical: 0 · High: 0 · Medium: 1 · Low: 0

If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).

- [Medium] The patch narrows who may transmit from a TX dmabuf binding.

--

net: devmem: check uid and netns in net_devmem_get_binding()

This commit stores the network namespace and sk_uid of the netlink socket
that created a dmabuf binding. net_devmem_get_binding() now rejects TX
sockets whose netns or sk_uid does not match. On a mismatch it returns
-EINVAL, the same error as a non-existent binding ID.

> diff --git a/net/core/devmem.c b/net/core/devmem.c
> index f4d60654ce7fd..9a773b1ce92de 100644
> --- a/net/core/devmem.c
> +++ b/net/core/devmem.c

[ ... ]

> @@ -220,6 +221,8 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
>  
>  	binding->dev = dev;
>  	binding->vdev = vdev;
> +	write_pnet(&binding->net, sock_net(nl_sk));
> +	binding->uid = sk_uid(nl_sk);
>  	binding->niov_shift = niov_shift;
>  	xa_init_flags(&binding->bound_rxqs, XA_FLAGS_ALLOC);
>  
> @@ -390,7 +393,9 @@ struct net_devmem_dmabuf_binding *net_devmem_get_binding(struct sock *sk,
>  	int err = 0;
>  
>  	binding = net_devmem_lookup_dmabuf(dmabuf_id);
> -	if (!binding || !binding->tx_vec) {
> +	if (!binding || !binding->tx_vec ||
> +	    !net_eq(sock_net(sk), read_pnet(&binding->net)) ||
> +	    !uid_eq(sk_uid(sk), binding->uid)) {
>  		err = -EINVAL;
>  		goto out_err;
>  	}

[Severity: Medium]
Could this break existing devmem TX users whose TCP socket and netlink
socket have different owners?

binding->uid comes from sk_uid(nl_sk), and the new check compares it with
sk_uid(sk) of the sending socket. sk_uid is the socket's owner. It is set
when the socket is created, in sock_init_data_uid(), or changed later by
sockfs_setattr(). It is not the caller's current credentials.

sock_graft() does not update sk_uid. An accepted TCP socket therefore keeps
the listener's sk_uid through sk_clone.

In these setups, every devmem sendmsg through
tcp_sendmsg_locked()->net_devmem_get_binding() would now fail with -EINVAL:

  - A listener created by root, or through systemd socket activation, where
    the service opens the netdev netlink socket after dropping privileges.
    binding->uid is then the service uid, while the accepted socket's
    sk_uid is 0.
  - A privileged helper that runs bind-tx and hands the binding IDs to
    workers running as other uids.
  - Sockets passed between uids with SCM_RIGHTS.

The mismatch returns the same -EINVAL as a stale ID. How would userspace
tell these cases apart?

Should Documentation/networking/devmem.rst be updated for the new
requirement? It still describes the ID as:

    The netlink API returns a dmabuf_id: a unique ID that refers to this
    dmabuf that has been bound.

It also lists only SO_ZEROCOPY / MSG_ZEROCOPY, plus an optional
SO_BINDTODEVICE, as TX socket requirements.

The comment above netdev_nl_bind_tx_doit() says:

net/core/netdev-genl.c:
 * shared NIC RX queues, bind-tx only DMA-maps the caller's dmabuf so they can
 * transmit from it on their own sockets without affecting other traffic or

That is not quite the same rule as "same sk_uid and same netns".

Because of the Fixes: tag, this restriction would also be backported to
stable. Should the commit message describe the compatibility impact?

-- 
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261005210403.3206872-1-kaifengw%40google.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH net] net: devmem: check uid and netns in net_devmem_get_binding()
  2026-10-08  0:04 ` netdev-bot+sashiko
@ 2026-10-08 21:40   ` Kaifeng Wang
  0 siblings, 0 replies; 7+ messages in thread
From: Kaifeng Wang @ 2026-10-08 21:40 UTC (permalink / raw)
  To: netdev-bot+sashiko
  Cc: netdev, almasrymina, edumazet, pabeni, willemb, davem, kuba,
	horms, sdf, bobbyeshleman, kaiyuanz, linux-kernel

> Could this break existing devmem TX users whose TCP socket and netlink
> socket have different owners?

This restriction is intentional. NETDEV_CMD_BIND_TX was made
unprivileged specifically so that an application can bind its own
dmabuf directly and transmit on its own sockets without needing a
separate privileged helper process. As noted in the comment above
netdev_nl_bind_tx_doit(), bind-tx is meant for the caller to transmit
"on their own sockets". We are not aware of any userspace workloads
that split bind-tx and TCP socket creation across different UIDs or
network namespaces.

> The mismatch returns the same -EINVAL as a stale ID. How would userspace
> tell these cases apart?

Returning -EINVAL on mismatch is deliberate: since dmabuf_id values
are allocated sequentially from a global xarray, returning a distinct
error code (for example -EPERM) would allow unprivileged users
to probe and enumerate active binding IDs belonging to other users.

On Wed, Oct 7, 2026 at 5:04 PM <netdev-bot+sashiko@kernel.org> wrote:
>
> Thank you for your contribution! Sashiko AI review found 1 potential
> issue(s) to consider.
>
> Critical: 0 · High: 0 · Medium: 1 · Low: 0
>
> If you believe none of the issues are legitimate, please reply to each
> issue of Medium severity or higher and explain why the AI is wrong.
> If any of them are legitimate and you plan to respin, please let patchwork
> know by including "pw-bot: cr" as a separate line at the end of your reply
> (one such reply per series is enough).
>
> - [Medium] The patch narrows who may transmit from a TX dmabuf binding.
>
> --
>
> net: devmem: check uid and netns in net_devmem_get_binding()
>
> This commit stores the network namespace and sk_uid of the netlink socket
> that created a dmabuf binding. net_devmem_get_binding() now rejects TX
> sockets whose netns or sk_uid does not match. On a mismatch it returns
> -EINVAL, the same error as a non-existent binding ID.
>
> > diff --git a/net/core/devmem.c b/net/core/devmem.c
> > index f4d60654ce7fd..9a773b1ce92de 100644
> > --- a/net/core/devmem.c
> > +++ b/net/core/devmem.c
>
> [ ... ]
>
> > @@ -220,6 +221,8 @@ net_devmem_bind_dmabuf(struct net_device *dev, void *vdev,
> >
> >       binding->dev = dev;
> >       binding->vdev = vdev;
> > +     write_pnet(&binding->net, sock_net(nl_sk));
> > +     binding->uid = sk_uid(nl_sk);
> >       binding->niov_shift = niov_shift;
> >       xa_init_flags(&binding->bound_rxqs, XA_FLAGS_ALLOC);
> >
> > @@ -390,7 +393,9 @@ struct net_devmem_dmabuf_binding *net_devmem_get_binding(struct sock *sk,
> >       int err = 0;
> >
> >       binding = net_devmem_lookup_dmabuf(dmabuf_id);
> > -     if (!binding || !binding->tx_vec) {
> > +     if (!binding || !binding->tx_vec ||
> > +         !net_eq(sock_net(sk), read_pnet(&binding->net)) ||
> > +         !uid_eq(sk_uid(sk), binding->uid)) {
> >               err = -EINVAL;
> >               goto out_err;
> >       }
>
> [Severity: Medium]
> Could this break existing devmem TX users whose TCP socket and netlink
> socket have different owners?
>
> binding->uid comes from sk_uid(nl_sk), and the new check compares it with
> sk_uid(sk) of the sending socket. sk_uid is the socket's owner. It is set
> when the socket is created, in sock_init_data_uid(), or changed later by
> sockfs_setattr(). It is not the caller's current credentials.
>
> sock_graft() does not update sk_uid. An accepted TCP socket therefore keeps
> the listener's sk_uid through sk_clone.
>
> In these setups, every devmem sendmsg through
> tcp_sendmsg_locked()->net_devmem_get_binding() would now fail with -EINVAL:
>
>   - A listener created by root, or through systemd socket activation, where
>     the service opens the netdev netlink socket after dropping privileges.
>     binding->uid is then the service uid, while the accepted socket's
>     sk_uid is 0.
>   - A privileged helper that runs bind-tx and hands the binding IDs to
>     workers running as other uids.
>   - Sockets passed between uids with SCM_RIGHTS.
>
> The mismatch returns the same -EINVAL as a stale ID. How would userspace
> tell these cases apart?
>
> Should Documentation/networking/devmem.rst be updated for the new
> requirement? It still describes the ID as:
>
>     The netlink API returns a dmabuf_id: a unique ID that refers to this
>     dmabuf that has been bound.
>
> It also lists only SO_ZEROCOPY / MSG_ZEROCOPY, plus an optional
> SO_BINDTODEVICE, as TX socket requirements.
>
> The comment above netdev_nl_bind_tx_doit() says:
>
> net/core/netdev-genl.c:
>  * shared NIC RX queues, bind-tx only DMA-maps the caller's dmabuf so they can
>  * transmit from it on their own sockets without affecting other traffic or
>
> That is not quite the same rule as "same sk_uid and same netns".
>
> Because of the Fixes: tag, this restriction would also be backported to
> stable. Should the commit message describe the compatibility impact?
>
> --
> Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261005210403.3206872-1-kaifengw%40google.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-10-08 21:41 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-05 21:04 [PATCH net] net: devmem: check uid and netns in net_devmem_get_binding() Kaifeng Wang
2026-10-05 21:09 ` netdev-bot+sinfo
2026-10-05 21:22   ` Kaifeng Wang
2026-10-05 22:24 ` Stanislav Fomichev
2026-10-06 16:19 ` Bobby Eshleman
2026-10-08  0:04 ` netdev-bot+sashiko
2026-10-08 21:40   ` Kaifeng Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox