net: Fail explicit bind to local reserved ports
Reserved ports may have some special use cases which are not suitable for use by general userspace applications. Currently, ports specified in ip_local_reserved_ports will not be returned only in case of automatic port assignment. Add a boolean sysctl flag 'reserved_port_bind'. Default value is 1 which preserves the existing behavior. Setting the value to 0 will prevent userspace applications from binding to these ports even when they are explicitly requested. BUG=20663075 Change-Id: Ib1071ca5bd437cd3c4f71b56147e4858f3b9ebec Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
This commit is contained in:
parent
63bb8bb2cc
commit
d04abc1ab2
6 changed files with 28 additions and 0 deletions
|
@ -829,6 +829,11 @@ ip_local_reserved_ports - list of comma separated ranges
|
|||
|
||||
Default: Empty
|
||||
|
||||
reserved_port_bind - BOOLEAN
|
||||
If set, allows explicit bind requests to applications requesting
|
||||
any port within the range of ip_local_reserved_ports.
|
||||
Default: 1
|
||||
|
||||
ip_nonlocal_bind - BOOLEAN
|
||||
If set, allows processes to bind() to non-local IP addresses,
|
||||
which can be quite useful - but may break some applications.
|
||||
|
|
|
@ -241,6 +241,8 @@ static inline int inet_is_local_reserved_port(struct net *net, int port)
|
|||
}
|
||||
#endif
|
||||
|
||||
extern int sysctl_reserved_port_bind;
|
||||
|
||||
/* From inetpeer.c */
|
||||
extern int inet_peer_threshold;
|
||||
extern int inet_peer_minttl;
|
||||
|
|
|
@ -135,6 +135,8 @@ static inline int current_has_network(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
int sysctl_reserved_port_bind __read_mostly = 1;
|
||||
|
||||
/* The inetsw table contains everything that inet_create needs to
|
||||
* build a new socket.
|
||||
*/
|
||||
|
|
|
@ -179,6 +179,13 @@ have_snum:
|
|||
head = &hashinfo->bhash[inet_bhashfn(net, snum,
|
||||
hashinfo->bhash_size)];
|
||||
spin_lock(&head->lock);
|
||||
|
||||
if (inet_is_local_reserved_port(net, snum) &&
|
||||
!sysctl_reserved_port_bind) {
|
||||
ret = 1;
|
||||
goto fail_unlock;
|
||||
}
|
||||
|
||||
inet_bind_bucket_for_each(tb, &head->chain)
|
||||
if (net_eq(ib_net(tb), net) && tb->port == snum)
|
||||
goto tb_found;
|
||||
|
|
|
@ -902,6 +902,13 @@ static struct ctl_table ipv4_net_table[] = {
|
|||
.mode = 0644,
|
||||
.proc_handler = proc_do_large_bitmap,
|
||||
},
|
||||
{
|
||||
.procname = "reserved_port_bind",
|
||||
.data = &sysctl_reserved_port_bind,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec
|
||||
},
|
||||
{
|
||||
.procname = "ip_no_pmtu_disc",
|
||||
.data = &init_net.ipv4.sysctl_ip_no_pmtu_disc,
|
||||
|
|
|
@ -257,6 +257,11 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
|
|||
} else {
|
||||
hslot = udp_hashslot(udptable, net, snum);
|
||||
spin_lock_bh(&hslot->lock);
|
||||
|
||||
if (inet_is_local_reserved_port(net, snum) &&
|
||||
!sysctl_reserved_port_bind)
|
||||
goto fail_unlock;
|
||||
|
||||
if (hslot->count > 10) {
|
||||
int exist;
|
||||
unsigned int slot2 = udp_sk(sk)->udp_portaddr_hash ^ snum;
|
||||
|
|
Loading…
Add table
Reference in a new issue