diff options
-rw-r--r-- | sys/security/mac_portacl/mac_portacl.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/sys/security/mac_portacl/mac_portacl.c b/sys/security/mac_portacl/mac_portacl.c index c7551bb6a5fb..07dd147e1ab5 100644 --- a/sys/security/mac_portacl/mac_portacl.c +++ b/sys/security/mac_portacl/mac_portacl.c @@ -79,6 +79,7 @@ #include <sys/sysctl.h> #include <netinet/in.h> +#include <netinet/in_pcb.h> #include <vm/vm.h> @@ -100,6 +101,13 @@ SYSCTL_INT(_security_mac_portacl, OID_AUTO, suser_exempt, CTLFLAG_RW, TUNABLE_INT("security.mac.portacl.suser_exempt", &mac_portacl_suser_exempt); +static int mac_portacl_autoport_exempt = 1; +SYSCTL_INT(_security_mac_portacl, OID_AUTO, autoport_exempt, CTLFLAG_RW, + &mac_portacl_autoport_exempt, 0, "Allow automatic allocation through " + "binding port 0 if not IP_PORTRANGELOW"); +TUNABLE_INT("security.mac.portacl.autoport_exempt", + &mac_portacl_autoport_exempt); + static int mac_portacl_port_high = 1023; SYSCTL_INT(_security_mac_portacl, OID_AUTO, port_high, CTLFLAG_RW, &mac_portacl_port_high, 0, "Highest port to enforce for"); @@ -434,6 +442,7 @@ check_socket_bind(struct ucred *cred, struct socket *so, struct label *socketlabel, struct sockaddr *sockaddr) { struct sockaddr_in *sin; + struct inpcb *inp; int family, type; u_int16_t port; @@ -461,6 +470,20 @@ check_socket_bind(struct ucred *cred, struct socket *so, sin = (struct sockaddr_in *) sockaddr; port = ntohs(sin->sin_port); + /* + * Sockets are frequently bound with a specific IP address but a port + * number of '0' to request automatic port allocation. This is often + * desirable as long as IP_PORTRANGELOW isn't set, which might permit + * automatic allocation of a "privileged" port. The autoport exempt + * flag exempts port 0 allocation from rule checking as long as a low + * port isn't required. + */ + if (mac_portacl_autoport_exempt && port == 0) { + inp = sotoinpcb(so); + if ((inp->inp_flags & INP_LOWPORT) == 0) + return (0); + } + return (rules_check(cred, family, type, port)); } |