Skip to content

Commit 7064d16

Browse files
committed
userns: Use kgids for sysctl_ping_group_range
- Store sysctl_ping_group_range as a paire of kgid_t values instead of a pair of gid_t values. - Move the kgid conversion work from ping_init_sock into ipv4_ping_group_range - For invalid cases reset to the default disabled state. With the kgid_t conversion made part of the original value sanitation from userspace understand how the code will react becomes clearer and it becomes possible to set the sysctl ping group range from something other than the initial user namespace. Cc: Vasiliy Kulikov <[email protected]> Acked-by: David S. Miller <[email protected]> Signed-off-by: Eric W. Biederman <[email protected]>
1 parent a7cb5a4 commit 7064d16

File tree

4 files changed

+35
-29
lines changed

4 files changed

+35
-29
lines changed

include/net/netns/ipv4.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#ifndef __NETNS_IPV4_H__
66
#define __NETNS_IPV4_H__
77

8+
#include <linux/uidgid.h>
89
#include <net/inet_frag.h>
910

1011
struct tcpm_hash_bucket;
@@ -62,7 +63,7 @@ struct netns_ipv4 {
6263
int sysctl_icmp_ratemask;
6364
int sysctl_icmp_errors_use_inbound_ifaddr;
6465

65-
unsigned int sysctl_ping_group_range[2];
66+
kgid_t sysctl_ping_group_range[2];
6667
long sysctl_tcp_mem[3];
6768

6869
atomic_t rt_genid;

init/Kconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -948,7 +948,6 @@ config UIDGID_CONVERTED
948948
depends on NETFILTER_XT_MATCH_RECENT = n
949949
depends on NETFILTER_XT_TARGET_LOG = n
950950
depends on NETFILTER_NETLINK_LOG = n
951-
depends on INET = n
952951
depends on IPV6 = n
953952
depends on AF_RXRPC = n
954953
depends on NET_KEY = n

net/ipv4/ping.c

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,10 @@ static struct sock *ping_v4_lookup(struct net *net, __be32 saddr, __be32 daddr,
185185
return sk;
186186
}
187187

188-
static void inet_get_ping_group_range_net(struct net *net, gid_t *low,
189-
gid_t *high)
188+
static void inet_get_ping_group_range_net(struct net *net, kgid_t *low,
189+
kgid_t *high)
190190
{
191-
gid_t *data = net->ipv4.sysctl_ping_group_range;
191+
kgid_t *data = net->ipv4.sysctl_ping_group_range;
192192
unsigned int seq;
193193

194194
do {
@@ -203,19 +203,13 @@ static void inet_get_ping_group_range_net(struct net *net, gid_t *low,
203203
static int ping_init_sock(struct sock *sk)
204204
{
205205
struct net *net = sock_net(sk);
206-
gid_t group = current_egid();
207-
gid_t range[2];
206+
kgid_t group = current_egid();
208207
struct group_info *group_info = get_current_groups();
209208
int i, j, count = group_info->ngroups;
210209
kgid_t low, high;
211210

212-
inet_get_ping_group_range_net(net, range, range+1);
213-
low = make_kgid(&init_user_ns, range[0]);
214-
high = make_kgid(&init_user_ns, range[1]);
215-
if (!gid_valid(low) || !gid_valid(high) || gid_lt(high, low))
216-
return -EACCES;
217-
218-
if (range[0] <= group && group <= range[1])
211+
inet_get_ping_group_range_net(net, &low, &high);
212+
if (gid_lte(low, group) && gid_lte(group, high))
219213
return 0;
220214

221215
for (i = 0; i < group_info->nblocks; i++) {

net/ipv4/sysctl_net_ipv4.c

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ static int ipv4_local_port_range(ctl_table *table, int write,
7676
}
7777

7878

79-
static void inet_get_ping_group_range_table(struct ctl_table *table, gid_t *low, gid_t *high)
79+
static void inet_get_ping_group_range_table(struct ctl_table *table, kgid_t *low, kgid_t *high)
8080
{
81-
gid_t *data = table->data;
81+
kgid_t *data = table->data;
8282
unsigned int seq;
8383
do {
8484
seq = read_seqbegin(&sysctl_local_ports.lock);
@@ -89,12 +89,12 @@ static void inet_get_ping_group_range_table(struct ctl_table *table, gid_t *low,
8989
}
9090

9191
/* Update system visible IP port range */
92-
static void set_ping_group_range(struct ctl_table *table, gid_t range[2])
92+
static void set_ping_group_range(struct ctl_table *table, kgid_t low, kgid_t high)
9393
{
94-
gid_t *data = table->data;
94+
kgid_t *data = table->data;
9595
write_seqlock(&sysctl_local_ports.lock);
96-
data[0] = range[0];
97-
data[1] = range[1];
96+
data[0] = low;
97+
data[1] = high;
9898
write_sequnlock(&sysctl_local_ports.lock);
9999
}
100100

@@ -103,21 +103,33 @@ static int ipv4_ping_group_range(ctl_table *table, int write,
103103
void __user *buffer,
104104
size_t *lenp, loff_t *ppos)
105105
{
106+
struct user_namespace *user_ns = current_user_ns();
106107
int ret;
107-
gid_t range[2];
108+
gid_t urange[2];
109+
kgid_t low, high;
108110
ctl_table tmp = {
109-
.data = &range,
110-
.maxlen = sizeof(range),
111+
.data = &urange,
112+
.maxlen = sizeof(urange),
111113
.mode = table->mode,
112114
.extra1 = &ip_ping_group_range_min,
113115
.extra2 = &ip_ping_group_range_max,
114116
};
115117

116-
inet_get_ping_group_range_table(table, range, range + 1);
118+
inet_get_ping_group_range_table(table, &low, &high);
119+
urange[0] = from_kgid_munged(user_ns, low);
120+
urange[1] = from_kgid_munged(user_ns, high);
117121
ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
118122

119-
if (write && ret == 0)
120-
set_ping_group_range(table, range);
123+
if (write && ret == 0) {
124+
low = make_kgid(user_ns, urange[0]);
125+
high = make_kgid(user_ns, urange[1]);
126+
if (!gid_valid(low) || !gid_valid(high) ||
127+
(urange[1] < urange[0]) || gid_lt(high, low)) {
128+
low = make_kgid(&init_user_ns, 1);
129+
high = make_kgid(&init_user_ns, 0);
130+
}
131+
set_ping_group_range(table, low, high);
132+
}
121133

122134
return ret;
123135
}
@@ -786,7 +798,7 @@ static struct ctl_table ipv4_net_table[] = {
786798
{
787799
.procname = "ping_group_range",
788800
.data = &init_net.ipv4.sysctl_ping_group_range,
789-
.maxlen = sizeof(init_net.ipv4.sysctl_ping_group_range),
801+
.maxlen = sizeof(gid_t)*2,
790802
.mode = 0644,
791803
.proc_handler = ipv4_ping_group_range,
792804
},
@@ -830,8 +842,8 @@ static __net_init int ipv4_sysctl_init_net(struct net *net)
830842
* Sane defaults - nobody may create ping sockets.
831843
* Boot scripts should set this to distro-specific group.
832844
*/
833-
net->ipv4.sysctl_ping_group_range[0] = 1;
834-
net->ipv4.sysctl_ping_group_range[1] = 0;
845+
net->ipv4.sysctl_ping_group_range[0] = make_kgid(&init_user_ns, 1);
846+
net->ipv4.sysctl_ping_group_range[1] = make_kgid(&init_user_ns, 0);
835847

836848
tcp_init_mem(net);
837849

0 commit comments

Comments
 (0)