From b0d226932e6522b19c45a2b2465cfea5ae3eead9 Mon Sep 17 00:00:00 2001 From: "Crist J. Clark" Date: Fri, 21 Feb 2003 05:28:27 +0000 Subject: [PATCH] The ancient and outdated concept of "privileged ports" in UNIX-type OSes has probably caused more problems than it ever solved. Allow the user to retire the old behavior by specifying their own privileged range with, net.inet.ip.portrange.reservedhigh default = IPPORT_RESERVED - 1 net.inet.ip.portrange.reservedlo default = 0 Now you can run that webserver without ever needing root at all. Or just imagine, an ftpd that can really drop privileges, rather than just set the euid, and still do PORT data transfers from 20/tcp. Two edge cases to note, # sysctl net.inet.ip.portrange.reservedhigh=0 Opens all ports to everyone, and, # sysctl net.inet.ip.portrange.reservedhigh=65535 Locks all network activity to root only (which could actually have been achieved before with ipfw(8), but is somewhat more complicated). For those who stick to the old religion that 0-1023 belong to root and root alone, don't touch the knobs (or even lock them by raising securelevel(8)), and nothing changes. --- sys/netinet/in_pcb.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 46f824dfece..316977c3a08 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -96,6 +96,14 @@ int ipport_lastauto = IPPORT_HILASTAUTO; /* 65535 */ int ipport_hifirstauto = IPPORT_HIFIRSTAUTO; /* 49152 */ int ipport_hilastauto = IPPORT_HILASTAUTO; /* 65535 */ +/* + * Reserved ports accessible only to root. There are significant + * security considerations that must be accounted for when changing these, + * but the security benefits can be great. Please be careful. + */ +int ipport_reservedhigh = IPPORT_RESERVED - 1; /* 1023 */ +int ipport_reservedlow = 0; + #define RANGECHK(var, min, max) \ if ((var) < (min)) { (var) = (min); } \ else if ((var) > (max)) { (var) = (max); } @@ -132,6 +140,10 @@ SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, hifirst, CTLTYPE_INT|CTLFLAG_RW, &ipport_hifirstauto, 0, &sysctl_net_ipport_check, "I", ""); SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, hilast, CTLTYPE_INT|CTLFLAG_RW, &ipport_hilastauto, 0, &sysctl_net_ipport_check, "I", ""); +SYSCTL_INT(_net_inet_ip_portrange, OID_AUTO, reservedhigh, + CTLFLAG_RW|CTLFLAG_SECURE, &ipport_reservedhigh, 0, ""); +SYSCTL_INT(_net_inet_ip_portrange, OID_AUTO, reservedlow, + CTLFLAG_RW|CTLFLAG_SECURE, &ipport_reservedlow, 0, ""); /* * in_pcb.c: manage the Protocol Control Blocks. @@ -288,8 +300,9 @@ in_pcbbind_setup(inp, nam, laddrp, lportp, td) if (lport) { struct inpcb *t; /* GROSS */ - if (ntohs(lport) < IPPORT_RESERVED && td && - suser_cred(td->td_ucred, PRISON_ROOT)) + if (ntohs(lport) <= ipport_reservedhigh && + ntohs(lport) >= ipport_reservedlow && + td && suser_cred(td->td_ucred, PRISON_ROOT)) return (EACCES); if (td && jailed(td->td_ucred)) prison = 1;