RE: [PATCH net v2] net: qualcomm: rmnet: require real-netns admin for bridging

From: subash.a.kasiviswanathan

Date: Mon Oct 05 2026 - 01:47:20 EST


> -----Original Message-----
> From: Jérémy Jean <Jeremy.Jean@xxxxxxxxxxxxxxxxx>
> Sent: Sunday, October 4, 2026 2:32 PM
> To: Subash Abhinov Kasiviswanathan
> <subash.a.kasiviswanathan@xxxxxxxxxxxxxxxx>; Sean Tranchetti
> <sean.tranchetti@xxxxxxxxxxxxxxxx>
> Cc: netdev@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; Jérémy Jean
> <Jeremy.Jean@xxxxxxxxxxxxxxxxx>; stable@xxxxxxxxxxxxxxx
> Subject: [PATCH net v2] net: qualcomm: rmnet: require real-netns admin for
> bridging
>
> An rmnet device keeps its link to the real device when moved to another
> network namespace. The bridge callbacks change the real port, but rtnetlink
> only checks CAP_NET_ADMIN in the slave device's namespace.
>
> Require CAP_NET_ADMIN in the real device's namespace before adding or
> removing a bridge. Use the slave device's namespace for the comparison, since
> that is the namespace rtnetlink authorized.
>
> Fixes: 60d58f971c10 ("net: qualcomm: rmnet: Implement bridge mode")
> Cc: stable@xxxxxxxxxxxxxxx
> Assisted-by: LLM
> Signed-off-by: Jérémy Jean <Jeremy.Jean@xxxxxxxxxxxxxxxxx>
> ---
>
> Changes in v2, after Subash Abhinov's review:
> - Add the teardown check and use slave_dev for both capability checks.
>
> v1: https://lore.kernel.org/all/20260821202845.4053530-2-
> Jeremy.Jean@xxxxxxxxxxxxxxxxx/
>
> .../ethernet/qualcomm/rmnet/rmnet_config.c | 20
> ++++++++++++++++++-
> 1 file changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
> b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
> index bed6f63facf2..62d7acb13e0c 100644
> --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
> +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
> @@ -441,6 +441,13 @@ int rmnet_add_bridge(struct net_device
> *rmnet_dev,
> struct rmnet_port *port, *slave_port;
> int err;
>
> + /* The rtnl path only checks CAP_NET_ADMIN against
> dev_net(slave_dev),
> + * but bridge mode below controls real_dev, which may live in another
> + * netns.
> + */
> + if (!rtnl_dev_link_net_capable(slave_dev, dev_net(real_dev)))
> + return -EPERM;
> +
> port = rmnet_get_port_rtnl(real_dev);
>
> /* If there is more than one rmnet dev attached, its probably being
> @@ -489,7 +496,18 @@ int rmnet_add_bridge(struct net_device
> *rmnet_dev, int rmnet_del_bridge(struct net_device *rmnet_dev,
> struct net_device *slave_dev)
> {
> - struct rmnet_port *port = rmnet_get_port_rtnl(slave_dev);
> + struct rmnet_priv *priv = netdev_priv(rmnet_dev);
> + struct net_device *real_dev = priv->real_dev;
> + struct rmnet_port *port;
> +
> + /* The rtnl path only checks CAP_NET_ADMIN against
> dev_net(slave_dev),
> + * but bridge teardown also updates real_dev, which may live in
> another
> + * netns.
> + */
> + if (!rtnl_dev_link_net_capable(slave_dev, dev_net(real_dev)))
> + return -EPERM;
> +
> + port = rmnet_get_port_rtnl(slave_dev);
>
> rmnet_unregister_bridge(port);
>

A similar patch was committed recently in net-next. Please refer to https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=26ee8cd69d46a14b37ba5e512084fe80d730127a