aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/sysctl_net_ipv4.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/sysctl_net_ipv4.c')
-rw-r--r--net/ipv4/sysctl_net_ipv4.c42
1 files changed, 27 insertions, 15 deletions
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 1b5ce96707a3..3e78c79b5586 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -76,9 +76,9 @@ static int ipv4_local_port_range(ctl_table *table, int write,
76} 76}
77 77
78 78
79static void inet_get_ping_group_range_table(struct ctl_table *table, gid_t *low, gid_t *high) 79static void inet_get_ping_group_range_table(struct ctl_table *table, kgid_t *low, kgid_t *high)
80{ 80{
81 gid_t *data = table->data; 81 kgid_t *data = table->data;
82 unsigned int seq; 82 unsigned int seq;
83 do { 83 do {
84 seq = read_seqbegin(&sysctl_local_ports.lock); 84 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,
89} 89}
90 90
91/* Update system visible IP port range */ 91/* Update system visible IP port range */
92static void set_ping_group_range(struct ctl_table *table, gid_t range[2]) 92static void set_ping_group_range(struct ctl_table *table, kgid_t low, kgid_t high)
93{ 93{
94 gid_t *data = table->data; 94 kgid_t *data = table->data;
95 write_seqlock(&sysctl_local_ports.lock); 95 write_seqlock(&sysctl_local_ports.lock);
96 data[0] = range[0]; 96 data[0] = low;
97 data[1] = range[1]; 97 data[1] = high;
98 write_sequnlock(&sysctl_local_ports.lock); 98 write_sequnlock(&sysctl_local_ports.lock);
99} 99}
100 100
@@ -103,21 +103,33 @@ static int ipv4_ping_group_range(ctl_table *table, int write,
103 void __user *buffer, 103 void __user *buffer,
104 size_t *lenp, loff_t *ppos) 104 size_t *lenp, loff_t *ppos)
105{ 105{
106 struct user_namespace *user_ns = current_user_ns();
106 int ret; 107 int ret;
107 gid_t range[2]; 108 gid_t urange[2];
109 kgid_t low, high;
108 ctl_table tmp = { 110 ctl_table tmp = {
109 .data = &range, 111 .data = &urange,
110 .maxlen = sizeof(range), 112 .maxlen = sizeof(urange),
111 .mode = table->mode, 113 .mode = table->mode,
112 .extra1 = &ip_ping_group_range_min, 114 .extra1 = &ip_ping_group_range_min,
113 .extra2 = &ip_ping_group_range_max, 115 .extra2 = &ip_ping_group_range_max,
114 }; 116 };
115 117
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);
117 ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); 121 ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
118 122
119 if (write && ret == 0) 123 if (write && ret == 0) {
120 set_ping_group_range(table, range); 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 }
121 133
122 return ret; 134 return ret;
123} 135}
@@ -786,7 +798,7 @@ static struct ctl_table ipv4_net_table[] = {
786 { 798 {
787 .procname = "ping_group_range", 799 .procname = "ping_group_range",
788 .data = &init_net.ipv4.sysctl_ping_group_range, 800 .data = &init_net.ipv4.sysctl_ping_group_range,
789 .maxlen = sizeof(init_net.ipv4.sysctl_ping_group_range), 801 .maxlen = sizeof(gid_t)*2,
790 .mode = 0644, 802 .mode = 0644,
791 .proc_handler = ipv4_ping_group_range, 803 .proc_handler = ipv4_ping_group_range,
792 }, 804 },
@@ -830,8 +842,8 @@ static __net_init int ipv4_sysctl_init_net(struct net *net)
830 * Sane defaults - nobody may create ping sockets. 842 * Sane defaults - nobody may create ping sockets.
831 * Boot scripts should set this to distro-specific group. 843 * Boot scripts should set this to distro-specific group.
832 */ 844 */
833 net->ipv4.sysctl_ping_group_range[0] = 1; 845 net->ipv4.sysctl_ping_group_range[0] = make_kgid(&init_user_ns, 1);
834 net->ipv4.sysctl_ping_group_range[1] = 0; 846 net->ipv4.sysctl_ping_group_range[1] = make_kgid(&init_user_ns, 0);
835 847
836 tcp_init_mem(net); 848 tcp_init_mem(net);
837 849