|
@@ -76,9 +76,9 @@ static int ipv4_local_port_range(ctl_table *table, int write,
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-static void inet_get_ping_group_range_table(struct ctl_table *table, gid_t *low, gid_t *high)
|
|
|
|
|
|
+static void inet_get_ping_group_range_table(struct ctl_table *table, kgid_t *low, kgid_t *high)
|
|
{
|
|
{
|
|
- gid_t *data = table->data;
|
|
|
|
|
|
+ kgid_t *data = table->data;
|
|
unsigned int seq;
|
|
unsigned int seq;
|
|
do {
|
|
do {
|
|
seq = read_seqbegin(&sysctl_local_ports.lock);
|
|
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,
|
|
}
|
|
}
|
|
|
|
|
|
/* Update system visible IP port range */
|
|
/* Update system visible IP port range */
|
|
-static void set_ping_group_range(struct ctl_table *table, gid_t range[2])
|
|
|
|
|
|
+static void set_ping_group_range(struct ctl_table *table, kgid_t low, kgid_t high)
|
|
{
|
|
{
|
|
- gid_t *data = table->data;
|
|
|
|
|
|
+ kgid_t *data = table->data;
|
|
write_seqlock(&sysctl_local_ports.lock);
|
|
write_seqlock(&sysctl_local_ports.lock);
|
|
- data[0] = range[0];
|
|
|
|
- data[1] = range[1];
|
|
|
|
|
|
+ data[0] = low;
|
|
|
|
+ data[1] = high;
|
|
write_sequnlock(&sysctl_local_ports.lock);
|
|
write_sequnlock(&sysctl_local_ports.lock);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -103,21 +103,33 @@ static int ipv4_ping_group_range(ctl_table *table, int write,
|
|
void __user *buffer,
|
|
void __user *buffer,
|
|
size_t *lenp, loff_t *ppos)
|
|
size_t *lenp, loff_t *ppos)
|
|
{
|
|
{
|
|
|
|
+ struct user_namespace *user_ns = current_user_ns();
|
|
int ret;
|
|
int ret;
|
|
- gid_t range[2];
|
|
|
|
|
|
+ gid_t urange[2];
|
|
|
|
+ kgid_t low, high;
|
|
ctl_table tmp = {
|
|
ctl_table tmp = {
|
|
- .data = &range,
|
|
|
|
- .maxlen = sizeof(range),
|
|
|
|
|
|
+ .data = &urange,
|
|
|
|
+ .maxlen = sizeof(urange),
|
|
.mode = table->mode,
|
|
.mode = table->mode,
|
|
.extra1 = &ip_ping_group_range_min,
|
|
.extra1 = &ip_ping_group_range_min,
|
|
.extra2 = &ip_ping_group_range_max,
|
|
.extra2 = &ip_ping_group_range_max,
|
|
};
|
|
};
|
|
|
|
|
|
- inet_get_ping_group_range_table(table, range, range + 1);
|
|
|
|
|
|
+ inet_get_ping_group_range_table(table, &low, &high);
|
|
|
|
+ urange[0] = from_kgid_munged(user_ns, low);
|
|
|
|
+ urange[1] = from_kgid_munged(user_ns, high);
|
|
ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
|
|
ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
|
|
|
|
|
|
- if (write && ret == 0)
|
|
|
|
- set_ping_group_range(table, range);
|
|
|
|
|
|
+ if (write && ret == 0) {
|
|
|
|
+ low = make_kgid(user_ns, urange[0]);
|
|
|
|
+ high = make_kgid(user_ns, urange[1]);
|
|
|
|
+ if (!gid_valid(low) || !gid_valid(high) ||
|
|
|
|
+ (urange[1] < urange[0]) || gid_lt(high, low)) {
|
|
|
|
+ low = make_kgid(&init_user_ns, 1);
|
|
|
|
+ high = make_kgid(&init_user_ns, 0);
|
|
|
|
+ }
|
|
|
|
+ set_ping_group_range(table, low, high);
|
|
|
|
+ }
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
@@ -786,7 +798,7 @@ static struct ctl_table ipv4_net_table[] = {
|
|
{
|
|
{
|
|
.procname = "ping_group_range",
|
|
.procname = "ping_group_range",
|
|
.data = &init_net.ipv4.sysctl_ping_group_range,
|
|
.data = &init_net.ipv4.sysctl_ping_group_range,
|
|
- .maxlen = sizeof(init_net.ipv4.sysctl_ping_group_range),
|
|
|
|
|
|
+ .maxlen = sizeof(gid_t)*2,
|
|
.mode = 0644,
|
|
.mode = 0644,
|
|
.proc_handler = ipv4_ping_group_range,
|
|
.proc_handler = ipv4_ping_group_range,
|
|
},
|
|
},
|
|
@@ -830,8 +842,8 @@ static __net_init int ipv4_sysctl_init_net(struct net *net)
|
|
* Sane defaults - nobody may create ping sockets.
|
|
* Sane defaults - nobody may create ping sockets.
|
|
* Boot scripts should set this to distro-specific group.
|
|
* Boot scripts should set this to distro-specific group.
|
|
*/
|
|
*/
|
|
- net->ipv4.sysctl_ping_group_range[0] = 1;
|
|
|
|
- net->ipv4.sysctl_ping_group_range[1] = 0;
|
|
|
|
|
|
+ net->ipv4.sysctl_ping_group_range[0] = make_kgid(&init_user_ns, 1);
|
|
|
|
+ net->ipv4.sysctl_ping_group_range[1] = make_kgid(&init_user_ns, 0);
|
|
|
|
|
|
tcp_init_mem(net);
|
|
tcp_init_mem(net);
|
|
|
|
|