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
|
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
|
ip_nonlocal_bind - BOOLEAN
|
||||||
If set, allows processes to bind() to non-local IP addresses,
|
If set, allows processes to bind() to non-local IP addresses,
|
||||||
which can be quite useful - but may break some applications.
|
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
|
#endif
|
||||||
|
|
||||||
|
extern int sysctl_reserved_port_bind;
|
||||||
|
|
||||||
/* From inetpeer.c */
|
/* From inetpeer.c */
|
||||||
extern int inet_peer_threshold;
|
extern int inet_peer_threshold;
|
||||||
extern int inet_peer_minttl;
|
extern int inet_peer_minttl;
|
||||||
|
|
|
@ -135,6 +135,8 @@ static inline int current_has_network(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int sysctl_reserved_port_bind __read_mostly = 1;
|
||||||
|
|
||||||
/* The inetsw table contains everything that inet_create needs to
|
/* The inetsw table contains everything that inet_create needs to
|
||||||
* build a new socket.
|
* build a new socket.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -179,6 +179,13 @@ have_snum:
|
||||||
head = &hashinfo->bhash[inet_bhashfn(net, snum,
|
head = &hashinfo->bhash[inet_bhashfn(net, snum,
|
||||||
hashinfo->bhash_size)];
|
hashinfo->bhash_size)];
|
||||||
spin_lock(&head->lock);
|
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)
|
inet_bind_bucket_for_each(tb, &head->chain)
|
||||||
if (net_eq(ib_net(tb), net) && tb->port == snum)
|
if (net_eq(ib_net(tb), net) && tb->port == snum)
|
||||||
goto tb_found;
|
goto tb_found;
|
||||||
|
|
|
@ -902,6 +902,13 @@ static struct ctl_table ipv4_net_table[] = {
|
||||||
.mode = 0644,
|
.mode = 0644,
|
||||||
.proc_handler = proc_do_large_bitmap,
|
.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",
|
.procname = "ip_no_pmtu_disc",
|
||||||
.data = &init_net.ipv4.sysctl_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 {
|
} else {
|
||||||
hslot = udp_hashslot(udptable, net, snum);
|
hslot = udp_hashslot(udptable, net, snum);
|
||||||
spin_lock_bh(&hslot->lock);
|
spin_lock_bh(&hslot->lock);
|
||||||
|
|
||||||
|
if (inet_is_local_reserved_port(net, snum) &&
|
||||||
|
!sysctl_reserved_port_bind)
|
||||||
|
goto fail_unlock;
|
||||||
|
|
||||||
if (hslot->count > 10) {
|
if (hslot->count > 10) {
|
||||||
int exist;
|
int exist;
|
||||||
unsigned int slot2 = udp_sk(sk)->udp_portaddr_hash ^ snum;
|
unsigned int slot2 = udp_sk(sk)->udp_portaddr_hash ^ snum;
|
||||||
|
|
Loading…
Add table
Reference in a new issue