aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/networking/ip-sysctl.txt9
-rw-r--r--include/net/ip.h10
-rw-r--r--include/net/netns/ipv4.h1
-rw-r--r--net/ipv4/af_inet.c5
-rw-r--r--net/ipv4/sysctl_net_ipv4.c50
-rw-r--r--net/ipv6/af_inet6.c3
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c7
-rw-r--r--net/sctp/socket.c10
-rw-r--r--security/selinux/hooks.c3
9 files changed, 86 insertions, 12 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index aa1bb49f1dc6..17f2e7791042 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -822,6 +822,15 @@ ip_local_reserved_ports - list of comma separated ranges
822 822
823 Default: Empty 823 Default: Empty
824 824
825ip_unprivileged_port_start - INTEGER
826 This is a per-namespace sysctl. It defines the first
827 unprivileged port in the network namespace. Privileged ports
828 require root or CAP_NET_BIND_SERVICE in order to bind to them.
829 To disable all privileged ports, set this to 0. It may not
830 overlap with the ip_local_reserved_ports range.
831
832 Default: 1024
833
825ip_nonlocal_bind - BOOLEAN 834ip_nonlocal_bind - BOOLEAN
826 If set, allows processes to bind() to non-local IP addresses, 835 If set, allows processes to bind() to non-local IP addresses,
827 which can be quite useful - but may break some applications. 836 which can be quite useful - but may break some applications.
diff --git a/include/net/ip.h b/include/net/ip.h
index ab6761a7c883..bf264a8db1ce 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -263,11 +263,21 @@ static inline bool sysctl_dev_name_is_allowed(const char *name)
263 return strcmp(name, "default") != 0 && strcmp(name, "all") != 0; 263 return strcmp(name, "default") != 0 && strcmp(name, "all") != 0;
264} 264}
265 265
266static inline int inet_prot_sock(struct net *net)
267{
268 return net->ipv4.sysctl_ip_prot_sock;
269}
270
266#else 271#else
267static inline int inet_is_local_reserved_port(struct net *net, int port) 272static inline int inet_is_local_reserved_port(struct net *net, int port)
268{ 273{
269 return 0; 274 return 0;
270} 275}
276
277static inline int inet_prot_sock(struct net *net)
278{
279 return PROT_SOCK;
280}
271#endif 281#endif
272 282
273__be32 inet_current_timestamp(void); 283__be32 inet_current_timestamp(void);
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 8e3f5b6f26d5..e365732b8051 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -135,6 +135,7 @@ struct netns_ipv4 {
135 135
136#ifdef CONFIG_SYSCTL 136#ifdef CONFIG_SYSCTL
137 unsigned long *sysctl_local_reserved_ports; 137 unsigned long *sysctl_local_reserved_ports;
138 int sysctl_ip_prot_sock;
138#endif 139#endif
139 140
140#ifdef CONFIG_IP_MROUTE 141#ifdef CONFIG_IP_MROUTE
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index aae410bb655a..28fe8da4e1ac 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -479,7 +479,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
479 479
480 snum = ntohs(addr->sin_port); 480 snum = ntohs(addr->sin_port);
481 err = -EACCES; 481 err = -EACCES;
482 if (snum && snum < PROT_SOCK && 482 if (snum && snum < inet_prot_sock(net) &&
483 !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) 483 !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
484 goto out; 484 goto out;
485 485
@@ -1700,6 +1700,9 @@ static __net_init int inet_init_net(struct net *net)
1700 net->ipv4.sysctl_ip_default_ttl = IPDEFTTL; 1700 net->ipv4.sysctl_ip_default_ttl = IPDEFTTL;
1701 net->ipv4.sysctl_ip_dynaddr = 0; 1701 net->ipv4.sysctl_ip_dynaddr = 0;
1702 net->ipv4.sysctl_ip_early_demux = 1; 1702 net->ipv4.sysctl_ip_early_demux = 1;
1703#ifdef CONFIG_SYSCTL
1704 net->ipv4.sysctl_ip_prot_sock = PROT_SOCK;
1705#endif
1703 1706
1704 return 0; 1707 return 0;
1705} 1708}
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index c8d283615c6f..1b861997fdc5 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -35,6 +35,8 @@ static int ip_local_port_range_min[] = { 1, 1 };
35static int ip_local_port_range_max[] = { 65535, 65535 }; 35static int ip_local_port_range_max[] = { 65535, 65535 };
36static int tcp_adv_win_scale_min = -31; 36static int tcp_adv_win_scale_min = -31;
37static int tcp_adv_win_scale_max = 31; 37static int tcp_adv_win_scale_max = 31;
38static int ip_privileged_port_min;
39static int ip_privileged_port_max = 65535;
38static int ip_ttl_min = 1; 40static int ip_ttl_min = 1;
39static int ip_ttl_max = 255; 41static int ip_ttl_max = 255;
40static int tcp_syn_retries_min = 1; 42static int tcp_syn_retries_min = 1;
@@ -79,7 +81,12 @@ static int ipv4_local_port_range(struct ctl_table *table, int write,
79 ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); 81 ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
80 82
81 if (write && ret == 0) { 83 if (write && ret == 0) {
82 if (range[1] < range[0]) 84 /* Ensure that the upper limit is not smaller than the lower,
85 * and that the lower does not encroach upon the privileged
86 * port limit.
87 */
88 if ((range[1] < range[0]) ||
89 (range[0] < net->ipv4.sysctl_ip_prot_sock))
83 ret = -EINVAL; 90 ret = -EINVAL;
84 else 91 else
85 set_local_port_range(net, range); 92 set_local_port_range(net, range);
@@ -88,6 +95,40 @@ static int ipv4_local_port_range(struct ctl_table *table, int write,
88 return ret; 95 return ret;
89} 96}
90 97
98/* Validate changes from /proc interface. */
99static int ipv4_privileged_ports(struct ctl_table *table, int write,
100 void __user *buffer, size_t *lenp, loff_t *ppos)
101{
102 struct net *net = container_of(table->data, struct net,
103 ipv4.sysctl_ip_prot_sock);
104 int ret;
105 int pports;
106 int range[2];
107 struct ctl_table tmp = {
108 .data = &pports,
109 .maxlen = sizeof(pports),
110 .mode = table->mode,
111 .extra1 = &ip_privileged_port_min,
112 .extra2 = &ip_privileged_port_max,
113 };
114
115 pports = net->ipv4.sysctl_ip_prot_sock;
116
117 ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
118
119 if (write && ret == 0) {
120 inet_get_local_port_range(net, &range[0], &range[1]);
121 /* Ensure that the local port range doesn't overlap with the
122 * privileged port range.
123 */
124 if (range[0] < pports)
125 ret = -EINVAL;
126 else
127 net->ipv4.sysctl_ip_prot_sock = pports;
128 }
129
130 return ret;
131}
91 132
92static void inet_get_ping_group_range_table(struct ctl_table *table, kgid_t *low, kgid_t *high) 133static void inet_get_ping_group_range_table(struct ctl_table *table, kgid_t *low, kgid_t *high)
93{ 134{
@@ -964,6 +1005,13 @@ static struct ctl_table ipv4_net_table[] = {
964 .extra2 = &one, 1005 .extra2 = &one,
965 }, 1006 },
966#endif 1007#endif
1008 {
1009 .procname = "ip_unprivileged_port_start",
1010 .maxlen = sizeof(int),
1011 .data = &init_net.ipv4.sysctl_ip_prot_sock,
1012 .mode = 0644,
1013 .proc_handler = ipv4_privileged_ports,
1014 },
967 { } 1015 { }
968}; 1016};
969 1017
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index aa42123bc301..04db40620ea6 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -302,7 +302,8 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
302 return -EINVAL; 302 return -EINVAL;
303 303
304 snum = ntohs(addr->sin6_port); 304 snum = ntohs(addr->sin6_port);
305 if (snum && snum < PROT_SOCK && !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) 305 if (snum && snum < inet_prot_sock(net) &&
306 !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
306 return -EACCES; 307 return -EACCES;
307 308
308 lock_sock(sk); 309 lock_sock(sk);
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 55e0169caa4c..8b7416f4e01a 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -426,10 +426,9 @@ ip_vs_service_find(struct netns_ipvs *ipvs, int af, __u32 fwmark, __u16 protocol
426 */ 426 */
427 svc = __ip_vs_service_find(ipvs, af, protocol, vaddr, vport); 427 svc = __ip_vs_service_find(ipvs, af, protocol, vaddr, vport);
428 428
429 if (svc == NULL 429 if (!svc && protocol == IPPROTO_TCP &&
430 && protocol == IPPROTO_TCP 430 atomic_read(&ipvs->ftpsvc_counter) &&
431 && atomic_read(&ipvs->ftpsvc_counter) 431 (vport == FTPDATA || ntohs(vport) >= inet_prot_sock(ipvs->net))) {
432 && (vport == FTPDATA || ntohs(vport) >= PROT_SOCK)) {
433 /* 432 /*
434 * Check if ftp service entry exists, the packet 433 * Check if ftp service entry exists, the packet
435 * might belong to FTP data connections. 434 * might belong to FTP data connections.
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index bee4dd3feabb..d699d2cbf275 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -360,7 +360,7 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
360 } 360 }
361 } 361 }
362 362
363 if (snum && snum < PROT_SOCK && 363 if (snum && snum < inet_prot_sock(net) &&
364 !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) 364 !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
365 return -EACCES; 365 return -EACCES;
366 366
@@ -1152,8 +1152,10 @@ static int __sctp_connect(struct sock *sk,
1152 * accept new associations, but it SHOULD NOT 1152 * accept new associations, but it SHOULD NOT
1153 * be permitted to open new associations. 1153 * be permitted to open new associations.
1154 */ 1154 */
1155 if (ep->base.bind_addr.port < PROT_SOCK && 1155 if (ep->base.bind_addr.port <
1156 !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) { 1156 inet_prot_sock(net) &&
1157 !ns_capable(net->user_ns,
1158 CAP_NET_BIND_SERVICE)) {
1157 err = -EACCES; 1159 err = -EACCES;
1158 goto out_free; 1160 goto out_free;
1159 } 1161 }
@@ -1818,7 +1820,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
1818 * but it SHOULD NOT be permitted to open new 1820 * but it SHOULD NOT be permitted to open new
1819 * associations. 1821 * associations.
1820 */ 1822 */
1821 if (ep->base.bind_addr.port < PROT_SOCK && 1823 if (ep->base.bind_addr.port < inet_prot_sock(net) &&
1822 !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) { 1824 !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) {
1823 err = -EACCES; 1825 err = -EACCES;
1824 goto out_unlock; 1826 goto out_unlock;
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c7c6619431d5..53cb6da5f1c6 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4365,7 +4365,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
4365 4365
4366 inet_get_local_port_range(sock_net(sk), &low, &high); 4366 inet_get_local_port_range(sock_net(sk), &low, &high);
4367 4367
4368 if (snum < max(PROT_SOCK, low) || snum > high) { 4368 if (snum < max(inet_prot_sock(sock_net(sk)), low) ||
4369 snum > high) {
4369 err = sel_netport_sid(sk->sk_protocol, 4370 err = sel_netport_sid(sk->sk_protocol,
4370 snum, &sid); 4371 snum, &sid);
4371 if (err) 4372 if (err)