Date: Tue, 23 Nov 2004 17:23:40 +0100 From: Michal Mertl <mime@traveller.cz> To: Robert Watson <rwatson@freebsd.org> Cc: freebsd-security@freebsd.org Subject: Re: mac_portacl and automatic port allocation Message-ID: <41A3640C.2060001@traveller.cz> In-Reply-To: <Pine.NEB.3.96L.1041123143713.66539P-100000@fledge.watson.org> References: <Pine.NEB.3.96L.1041123143713.66539P-100000@fledge.watson.org>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------050001000402070006050702 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Robert Watson wrote(a): > On Sun, 21 Nov 2004, Michal Mertl wrote: > > >>I really like the idea behind mac_portacl but I find it difficult to use >>it because of one issue. When an unprivileged program binds to high >>automatic port with a call to bind(2) and port number set to 0 the >>system chooses the port to bind to itself. This mechanismus is used by >>number of programs, most commonly by ftp clients in active mode. >>Unfortunately this 0 is checked by the mac_portacl(4) module and the >>call to bind is refused. Rather simple fix would be to check if the >>local port is 0 and user hasn't asked for IP_PORTRANGE_LOW and then >>allow the call to trivially succeed. It can be controlled by a sysctl if >>needed. >> >>What do you think of the patch below? > > > Seems like a good change to me. Technically, there's probably a slight > atomicity problem relating to threads, since one thread could change the > flag while another thread is making the call to bind the socket. I'm not > sure that's easily fixed without a specific MAC check in the inet code, > and what you propose is certainly a big improvement over what is there. I noticed this potential problem. I don't think it's too serious. But it may possibly allow attacker to bind to low ports, potentially block legal use of them. That's why I offered the behavior in this case may be controlled by a sysctl. Extended patch attached. Binding to zero is disabled by default. > > I'll get this, sans the printf, merged sometime today. > Thank you. > Thanks! > > Robert N M Watson FreeBSD Core Team, TrustedBSD Projects > robert@fledge.watson.org Principal Research Scientist, McAfee Research > > > > --------------050001000402070006050702 Content-Type: text/plain; name="mac_portacl.c.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="mac_portacl.c.diff" --- mac_portacl.c.orig Tue Nov 23 17:02:05 2004 +++ mac_portacl.c Tue Nov 23 17:08:39 2004 @@ -79,6 +79,7 @@ #include <sys/sysctl.h> #include <netinet/in.h> +#include <netinet/in_pcb.h> #include <vm/vm.h> @@ -100,6 +101,12 @@ TUNABLE_INT("security.mac.portacl.suser_exempt", &mac_portacl_suser_exempt); +static int mac_portacl_allow_bind_zero = 0; +SYSCTL_INT(_security_mac_portacl, OID_AUTO, allow_bind_zero, CTLFLAG_RW, + &mac_portacl_allow_bind_zero, 0, "Whether binding to port 0 (system chooses the port automaticaly) is permitted"); +TUNABLE_INT("security.mac.portacl.allow_bind_zero", + &mac_portacl_allow_bind_zero); + 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"); @@ -441,6 +448,7 @@ struct label *socketlabel, struct sockaddr *sockaddr) { struct sockaddr_in *sin; + struct inpcb *inp = sotoinpcb(so); int family, type; u_int16_t port; @@ -467,6 +475,11 @@ type = so->so_type; sin = (struct sockaddr_in *) sockaddr; port = ntohs(sin->sin_port); + /* If port == 0 and user hasn't asked for IP_PORTRANGELOW return + success */ + if (mac_portacl_allow_bind_zero && port == 0 && + (inp->inp_flags & INP_LOWPORT) == 0) + return (0); return (rules_check(cred, family, type, port)); } --------------050001000402070006050702--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?41A3640C.2060001>