Skip to content

Commit 7f5611c

Browse files
matttbekuba-moo
authored andcommitted
rds: sysctl: rds_tcp_{rcv,snd}buf: avoid using current->nsproxy
As mentioned in a previous commit of this series, using the 'net' structure via 'current' is not recommended for different reasons: - Inconsistency: getting info from the reader's/writer's netns vs only from the opener's netns. - current->nsproxy can be NULL in some cases, resulting in an 'Oops' (null-ptr-deref), e.g. when the current task is exiting, as spotted by syzbot [1] using acct(2). The per-netns structure can be obtained from the table->data using container_of(), then the 'net' one can be retrieved from the listen socket (if available). Fixes: c6a58ff ("RDS: TCP: Add sysctl tunables for sndbuf/rcvbuf on rds-tcp socket") Cc: [email protected] Link: https://lore.kernel.org/[email protected] [1] Suggested-by: Al Viro <[email protected]> Signed-off-by: Matthieu Baerts (NGI0) <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 6259d24 commit 7f5611c

File tree

1 file changed

+32
-7
lines changed

1 file changed

+32
-7
lines changed

net/rds/tcp.c

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,10 @@ static atomic_t rds_tcp_unloading = ATOMIC_INIT(0);
6161

6262
static struct kmem_cache *rds_tcp_conn_slab;
6363

64-
static int rds_tcp_skbuf_handler(const struct ctl_table *ctl, int write,
65-
void *buffer, size_t *lenp, loff_t *fpos);
64+
static int rds_tcp_sndbuf_handler(const struct ctl_table *ctl, int write,
65+
void *buffer, size_t *lenp, loff_t *fpos);
66+
static int rds_tcp_rcvbuf_handler(const struct ctl_table *ctl, int write,
67+
void *buffer, size_t *lenp, loff_t *fpos);
6668

6769
static int rds_tcp_min_sndbuf = SOCK_MIN_SNDBUF;
6870
static int rds_tcp_min_rcvbuf = SOCK_MIN_RCVBUF;
@@ -74,7 +76,7 @@ static struct ctl_table rds_tcp_sysctl_table[] = {
7476
/* data is per-net pointer */
7577
.maxlen = sizeof(int),
7678
.mode = 0644,
77-
.proc_handler = rds_tcp_skbuf_handler,
79+
.proc_handler = rds_tcp_sndbuf_handler,
7880
.extra1 = &rds_tcp_min_sndbuf,
7981
},
8082
#define RDS_TCP_RCVBUF 1
@@ -83,7 +85,7 @@ static struct ctl_table rds_tcp_sysctl_table[] = {
8385
/* data is per-net pointer */
8486
.maxlen = sizeof(int),
8587
.mode = 0644,
86-
.proc_handler = rds_tcp_skbuf_handler,
88+
.proc_handler = rds_tcp_rcvbuf_handler,
8789
.extra1 = &rds_tcp_min_rcvbuf,
8890
},
8991
};
@@ -682,10 +684,10 @@ static void rds_tcp_sysctl_reset(struct net *net)
682684
spin_unlock_irq(&rds_tcp_conn_lock);
683685
}
684686

685-
static int rds_tcp_skbuf_handler(const struct ctl_table *ctl, int write,
687+
static int rds_tcp_skbuf_handler(struct rds_tcp_net *rtn,
688+
const struct ctl_table *ctl, int write,
686689
void *buffer, size_t *lenp, loff_t *fpos)
687690
{
688-
struct net *net = current->nsproxy->net_ns;
689691
int err;
690692

691693
err = proc_dointvec_minmax(ctl, write, buffer, lenp, fpos);
@@ -694,11 +696,34 @@ static int rds_tcp_skbuf_handler(const struct ctl_table *ctl, int write,
694696
*(int *)(ctl->extra1));
695697
return err;
696698
}
697-
if (write)
699+
700+
if (write && rtn->rds_tcp_listen_sock && rtn->rds_tcp_listen_sock->sk) {
701+
struct net *net = sock_net(rtn->rds_tcp_listen_sock->sk);
702+
698703
rds_tcp_sysctl_reset(net);
704+
}
705+
699706
return 0;
700707
}
701708

709+
static int rds_tcp_sndbuf_handler(const struct ctl_table *ctl, int write,
710+
void *buffer, size_t *lenp, loff_t *fpos)
711+
{
712+
struct rds_tcp_net *rtn = container_of(ctl->data, struct rds_tcp_net,
713+
sndbuf_size);
714+
715+
return rds_tcp_skbuf_handler(rtn, ctl, write, buffer, lenp, fpos);
716+
}
717+
718+
static int rds_tcp_rcvbuf_handler(const struct ctl_table *ctl, int write,
719+
void *buffer, size_t *lenp, loff_t *fpos)
720+
{
721+
struct rds_tcp_net *rtn = container_of(ctl->data, struct rds_tcp_net,
722+
rcvbuf_size);
723+
724+
return rds_tcp_skbuf_handler(rtn, ctl, write, buffer, lenp, fpos);
725+
}
726+
702727
static void rds_tcp_exit(void)
703728
{
704729
rds_tcp_set_unloading();

0 commit comments

Comments
 (0)