Hello,
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?
Index: mac_portacl.c
==================================================================RCS file:
/home/fcvs/cvs/src/sys/security/mac_portacl/mac_portacl.c,v
retrieving revision 1.5
diff -u -r1.5 mac_portacl.c
--- mac_portacl.c 15 May 2004 20:55:19 -0000 1.5
+++ mac_portacl.c 21 Nov 2004 21:25:49 -0000
@@ -79,6 +79,7 @@
#include <sys/sysctl.h>
#include <netinet/in.h>
+#include <netinet/in_pcb.h>
#include <vm/vm.h>
@@ -441,6 +442,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 +469,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 */
+ printf("mac_portacl: port %d, inp_flags: 0x%X\n", port,
inp->inp_flags);
+ if (port == 0 && (inp->inp_flags & INP_LOWPORT) == 0)
+ return (0);
return (rules_check(cred, family, type, port));
}
----------------
Best regards
--
Michal Mertl