Commit 82f31ebf authored by Maciej Żenczykowski's avatar Maciej Żenczykowski Committed by David S. Miller

net: port < inet_prot_sock(net) --> inet_port_requires_bind_service(net, port)

Note that the sysctl write accessor functions guarantee that:
  net->ipv4.sysctl_ip_prot_sock <= net->ipv4.ip_local_ports.range[0]
invariant is maintained, and as such the max() in selinux hooks is actually spurious.

ie. even though
  if (snum < max(inet_prot_sock(sock_net(sk)), low) || snum > high) {
per logic is the same as
  if ((snum < inet_prot_sock(sock_net(sk)) && snum < low) || snum > high) {
it is actually functionally equivalent to:
  if (snum < low || snum > high) {
which is equivalent to:
  if (snum < inet_prot_sock(sock_net(sk)) || snum < low || snum > high) {
even though the first clause is spurious.

But we want to hold on to it in case we ever want to change what what
inet_port_requires_bind_service() means (for example by changing
it from a, by default, [0..1024) range to some sort of set).

Test: builds, git 'grep inet_prot_sock' finds no other references
Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: default avatarMaciej Żenczykowski <maze@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e94a5d16
...@@ -351,9 +351,9 @@ static inline bool sysctl_dev_name_is_allowed(const char *name) ...@@ -351,9 +351,9 @@ static inline bool sysctl_dev_name_is_allowed(const char *name)
return strcmp(name, "default") != 0 && strcmp(name, "all") != 0; return strcmp(name, "default") != 0 && strcmp(name, "all") != 0;
} }
static inline int inet_prot_sock(struct net *net) static inline bool inet_port_requires_bind_service(struct net *net, unsigned short port)
{ {
return net->ipv4.sysctl_ip_prot_sock; return port < net->ipv4.sysctl_ip_prot_sock;
} }
#else #else
...@@ -362,9 +362,9 @@ static inline bool inet_is_local_reserved_port(struct net *net, int port) ...@@ -362,9 +362,9 @@ static inline bool inet_is_local_reserved_port(struct net *net, int port)
return false; return false;
} }
static inline int inet_prot_sock(struct net *net) static inline bool inet_port_requires_bind_service(struct net *net, unsigned short port)
{ {
return PROT_SOCK; return port < PROT_SOCK;
} }
#endif #endif
......
...@@ -495,7 +495,7 @@ int __inet_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len, ...@@ -495,7 +495,7 @@ int __inet_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
snum = ntohs(addr->sin_port); snum = ntohs(addr->sin_port);
err = -EACCES; err = -EACCES;
if (snum && snum < inet_prot_sock(net) && if (snum && inet_port_requires_bind_service(net, snum) &&
!ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
goto out; goto out;
......
...@@ -292,7 +292,7 @@ static int __inet6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len, ...@@ -292,7 +292,7 @@ static int __inet6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
return -EINVAL; return -EINVAL;
snum = ntohs(addr->sin6_port); snum = ntohs(addr->sin6_port);
if (snum && snum < inet_prot_sock(net) && if (snum && inet_port_requires_bind_service(net, snum) &&
!ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
return -EACCES; return -EACCES;
......
...@@ -423,7 +423,7 @@ ip_vs_service_find(struct netns_ipvs *ipvs, int af, __u32 fwmark, __u16 protocol ...@@ -423,7 +423,7 @@ ip_vs_service_find(struct netns_ipvs *ipvs, int af, __u32 fwmark, __u16 protocol
if (!svc && protocol == IPPROTO_TCP && if (!svc && protocol == IPPROTO_TCP &&
atomic_read(&ipvs->ftpsvc_counter) && atomic_read(&ipvs->ftpsvc_counter) &&
(vport == FTPDATA || ntohs(vport) >= inet_prot_sock(ipvs->net))) { (vport == FTPDATA || !inet_port_requires_bind_service(ipvs->net, ntohs(vport)))) {
/* /*
* Check if ftp service entry exists, the packet * Check if ftp service entry exists, the packet
* might belong to FTP data connections. * might belong to FTP data connections.
......
...@@ -384,7 +384,7 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len) ...@@ -384,7 +384,7 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
} }
} }
if (snum && snum < inet_prot_sock(net) && if (snum && inet_port_requires_bind_service(net, snum) &&
!ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
return -EACCES; return -EACCES;
...@@ -1061,7 +1061,7 @@ static int sctp_connect_new_asoc(struct sctp_endpoint *ep, ...@@ -1061,7 +1061,7 @@ static int sctp_connect_new_asoc(struct sctp_endpoint *ep,
if (sctp_autobind(sk)) if (sctp_autobind(sk))
return -EAGAIN; return -EAGAIN;
} else { } else {
if (ep->base.bind_addr.port < inet_prot_sock(net) && if (inet_port_requires_bind_service(net, ep->base.bind_addr.port) &&
!ns_capable(net->user_ns, CAP_NET_BIND_SERVICE)) !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
return -EACCES; return -EACCES;
} }
......
...@@ -4623,8 +4623,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in ...@@ -4623,8 +4623,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
inet_get_local_port_range(sock_net(sk), &low, &high); inet_get_local_port_range(sock_net(sk), &low, &high);
if (snum < max(inet_prot_sock(sock_net(sk)), low) || if (inet_port_requires_bind_service(sock_net(sk), snum) ||
snum > high) { snum < low || snum > high) {
err = sel_netport_sid(sk->sk_protocol, err = sel_netport_sid(sk->sk_protocol,
snum, &sid); snum, &sid);
if (err) if (err)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment