linux/include
Maciej Żenczykowski 8a4b8ea595 ANDROID: net: introduce ip_local_unbindable_ports sysctl
and associated inet_is_local_unbindable_port() helper function:
use it to make explicitly binding to an unbindable port return
-EPERM 'Operation not permitted'.

Autobind doesn't honour this new sysctl since:
  (a) you can simply set both if that's the behaviour you desire
  (b) there could be a use for preventing explicit while allowing auto
  (c) it's faster in the relatively critical path of doing port selection
      during connect() to only check one bitmap instead of both

Various ports may have special use cases which are not suitable for
use by general userspace applications. Currently, ports specified in
ip_local_reserved_ports sysctl will not be returned only in case of
automatic port assignment, but nothing prevents you from explicitly
binding to them - even from an entirely unprivileged process.

In certain cases it is desirable to prevent the host from assigning the
ports even in case of explicit binds, even from superuser processes.

Example use cases might be:
 - a port being stolen by the nic for remote serial console, remote
   power management or some other sort of debugging functionality
   (crash collection, gdb, direct access to some other microcontroller
   on the nic or motherboard, remote management of the nic itself).
 - a transparent proxy where packets are being redirected: in case
   a socket matches this connection, packets from this application
   would be incorrectly sent to one of the endpoints.

Initially I wanted to solve this problem via the simple one line:

static inline bool inet_port_requires_bind_service(struct net *net, unsigned short port) {
-       return port < net->ipv4.sysctl_ip_prot_sock;
+       return port < net->ipv4.sysctl_ip_prot_sock || inet_is_local_reserved_port(net, port);
}

However, this doesn't work for two reasons:
  (a) it changes userspace visible behaviour of the existing local
      reserved ports sysctl, and there appears to be enough documentation
      on the internet talking about setting it to make this a bad idea
  (b) it doesn't prevent privileged apps from using these ports,
      CAP_BIND_SERVICE is relatively likely to be available to, for example,
      a recursive DNS server so it can listed on port 53, which also needs
      to do src port randomization for outgoing queries due to security
      reasons (and it thus does manual port binding).

If we *know* that certain ports are simply unusable, then it's better
nothing even gets the opportunity to try to use them.  This way we at
least get a quick failure, instead of some sort of timeout (or possibly
even corruption of the data stream of the non-kernel based use case).

Test:
  vm:~# cat /proc/sys/net/ipv4/ip_local_unbindable_ports

  vm:~# python -c 'import socket; s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM, 0); s.bind(("::", 3967))'
  vm:~# python -c 'import socket; s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, 0); s.bind(("::", 3967))'
  vm:~# echo 3967 > /proc/sys/net/ipv4/ip_local_unbindable_ports
  vm:~# cat /proc/sys/net/ipv4/ip_local_unbindable_ports
  3967
  vm:~# python -c 'import socket; s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM, 0); s.bind(("::", 3967))'
  socket.error: (1, 'Operation not permitted')
  vm:~# python -c 'import socket; s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, 0); s.bind(("::", 3967))'
  socket.error: (1, 'Operation not permitted')

Cc: Sean Tranchetti <stranche@codeaurora.org>
Cc: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Linux SCTP <linux-sctp@vger.kernel.org>
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Bug: 140404597
Change-Id: Ie96207bea90ae1345adf7b45724d0caf4d6e52c2
Signed-off-by: Todd Kjos <tkjos@google.com>
Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
2021-02-09 15:49:37 +00:00
..
acpi PM: ACPI: PCI: Drop acpi_pm_set_bridge_wakeup() 2020-12-30 11:54:05 +01:00
asm-generic FROMGIT: asm-generic: export: Stub EXPORT_SYMBOL with __DISABLE_EXPORTS 2021-02-05 17:37:36 +00:00
clocksource
crypto
drm Merge 65b55d4c85 ("Merge tag 'arm-soc-fixes-v5.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc") into android-mainline 2020-11-02 11:04:03 +01:00
dt-bindings UPSTREAM: dt-bindings: connector: Add SVDM VDO properties 2021-02-09 11:55:09 +01:00
keys
kunit kunit: fix display of failed expectations for strings 2020-11-10 13:45:15 -07:00
kvm UPSTREAM: KVM: arm64: Replace KVM_ARM_PMU with HW_PERF_EVENTS 2021-01-28 17:57:18 +00:00
linux UPSTREAM: usb: pd: Make SVDM Version configurable in VDM header 2021-02-09 11:51:55 +01:00
math-emu
media Merge 5.10.4 into android12-5.10 2020-12-30 12:47:03 +01:00
memory
misc
net ANDROID: net: introduce ip_local_unbindable_ports sysctl 2021-02-09 15:49:37 +00:00
pcmcia
ras mm,hwpoison: introduce MF_MSG_UNSPLIT_THP 2020-10-16 11:11:17 -07:00
rdma RDMA/core: remove use of dma_virt_ops 2021-01-09 13:46:24 +01:00
scsi scsi: libiscsi: Fix NOP race condition 2020-11-16 22:32:50 -05:00
soc net: mscc: ocelot: fix dropping of unknown IPv4 multicast on Seville 2020-12-05 15:41:34 -08:00
sound Merge 27bba9c532 ("Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi") into android-mainline 2020-11-22 10:00:49 +01:00
target
trace FROMGIT: tracing: add error_report_end trace point 2021-02-05 09:20:54 -08:00
uapi UPSTREAM: userfaultfd: add UFFD_USER_MODE_ONLY 2021-02-05 13:14:00 +00:00
vdso
video gpu: ipu-v3: remove unused functions 2020-10-26 10:42:38 +01:00
xen xen: Fix event channel callback via INTX/GSI 2021-01-27 11:55:00 +01:00