]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net/rds: Restrict use of RDS/IB to the initial network namespace
authorGreg Jumper <greg.jumper@oracle.com>
Wed, 8 Apr 2026 08:04:20 +0000 (01:04 -0700)
committerJakub Kicinski <kuba@kernel.org>
Sun, 12 Apr 2026 20:33:19 +0000 (13:33 -0700)
Prevent using RDS/IB in network namespaces other than the initial one.
The existing RDS/IB code will not work properly in non-initial network
namespaces.

Fixes: d5a8ac28a7ff ("RDS-TCP: Make RDS-TCP work correctly when it is set up in a netns other than init_net")
Reported-by: syzbot+da8e060735ae02c8f3d1@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=da8e060735ae02c8f3d1
Signed-off-by: Greg Jumper <greg.jumper@oracle.com>
Signed-off-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260408080420.540032-3-achender@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/rds/af_rds.c
net/rds/ib.c

index b396c673dfaf62166b58a6dce9d3e64b60309ade..76f625986a7f24aadf2cf6da529a5370feadb1d2 100644 (file)
@@ -357,7 +357,8 @@ static int rds_cong_monitor(struct rds_sock *rs, sockptr_t optval, int optlen)
        return ret;
 }
 
-static int rds_set_transport(struct rds_sock *rs, sockptr_t optval, int optlen)
+static int rds_set_transport(struct net *net, struct rds_sock *rs,
+                            sockptr_t optval, int optlen)
 {
        int t_type;
 
@@ -373,6 +374,10 @@ static int rds_set_transport(struct rds_sock *rs, sockptr_t optval, int optlen)
        if (t_type < 0 || t_type >= RDS_TRANS_COUNT)
                return -EINVAL;
 
+       /* RDS/IB is restricted to the initial network namespace */
+       if (t_type != RDS_TRANS_TCP && !net_eq(net, &init_net))
+               return -EPROTOTYPE;
+
        rs->rs_transport = rds_trans_get(t_type);
 
        return rs->rs_transport ? 0 : -ENOPROTOOPT;
@@ -433,6 +438,7 @@ static int rds_setsockopt(struct socket *sock, int level, int optname,
                          sockptr_t optval, unsigned int optlen)
 {
        struct rds_sock *rs = rds_sk_to_rs(sock->sk);
+       struct net *net = sock_net(sock->sk);
        int ret;
 
        if (level != SOL_RDS) {
@@ -461,7 +467,7 @@ static int rds_setsockopt(struct socket *sock, int level, int optname,
                break;
        case SO_RDS_TRANSPORT:
                lock_sock(sock->sk);
-               ret = rds_set_transport(rs, optval, optlen);
+               ret = rds_set_transport(net, rs, optval, optlen);
                release_sock(sock->sk);
                break;
        case SO_TIMESTAMP_OLD:
index 412ff61e74fac681d353dae06db5c01dd6ee0a43..39f87272e071bf6f8c87587c5527bee7627ec698 100644 (file)
@@ -492,6 +492,10 @@ static int rds_ib_laddr_check(struct net *net, const struct in6_addr *addr,
 {
        struct rds_ib_device *rds_ibdev = NULL;
 
+       /* RDS/IB is restricted to the initial network namespace */
+       if (!net_eq(net, &init_net))
+               return -EPROTOTYPE;
+
        if (ipv6_addr_v4mapped(addr)) {
                rds_ibdev = rds_ib_get_device(addr->s6_addr32[3]);
                if (rds_ibdev) {