summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Gross <vgross@cvs.openbsd.org>2016-06-18 10:36:14 +0000
committerVincent Gross <vgross@cvs.openbsd.org>2016-06-18 10:36:14 +0000
commita2a69e4ebbc39b9b06527f05a765ce43782dbc45 (patch)
tree7b8fd3554d8f4b9187d0a126a349ab6c5e67c4cc
parent3cf9a9daf049acc0fdc14eef9e6541f6cdeea457 (diff)
Add net.inet.{tcp,udp}.rootonly sysctl, to mark which ports
cannot be bound to by non-root users. Ok millert@ bluhm@
-rw-r--r--lib/libc/gen/sysctl.321
-rw-r--r--sbin/sysctl/sysctl.86
-rw-r--r--sbin/sysctl/sysctl.c8
-rw-r--r--sys/netinet/in_pcb.c21
-rw-r--r--sys/netinet/in_pcb.h11
-rw-r--r--sys/netinet/ip_input.c11
-rw-r--r--sys/netinet/tcp_usrreq.c8
-rw-r--r--sys/netinet/tcp_var.h7
-rw-r--r--sys/netinet/udp_usrreq.c8
-rw-r--r--sys/netinet/udp_var.h9
10 files changed, 92 insertions, 18 deletions
diff --git a/lib/libc/gen/sysctl.3 b/lib/libc/gen/sysctl.3
index 1fa623b92f1..ff46b7c141a 100644
--- a/lib/libc/gen/sysctl.3
+++ b/lib/libc/gen/sysctl.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sysctl.3,v 1.261 2016/06/07 05:52:49 tim Exp $
+.\" $OpenBSD: sysctl.3,v 1.262 2016/06/18 10:36:13 vgross Exp $
.\"
.\" Copyright (c) 1993
.\" The Regents of the University of California. All rights reserved.
@@ -27,7 +27,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 7 2016 $
+.Dd $Mdocdate: June 18 2016 $
.Dt SYSCTL 3
.Os
.Sh NAME
@@ -1201,11 +1201,13 @@ The currently defined protocols and names are:
.It tcp Ta synbucketlimit Ta integer Ta yes
.It tcp Ta syncachelimit Ta integer Ta yes
.It tcp Ta synuselimit Ta integer Ta yes
+.It tcp Ta rootonly Ta array Ta yes
.It udp Ta baddynamic Ta array Ta yes
.It udp Ta checksum Ta integer Ta yes
.It udp Ta recvspace Ta integer Ta yes
.It udp Ta sendspace Ta integer Ta yes
.It udp Ta stats Ta structure Ta no
+.It udp Ta rootonly Ta array Ta yes
.El
.Pp
The variables are as follows:
@@ -1618,6 +1620,15 @@ The maximum number of entries allowed in the TCP SYN cache.
.It Li tcp.synuselimit
The minimum number of times the hash function for the TCP SYN cache is used
before it is reseeded.
+.It Li tcp.rootonly
+An array of
+.Li in_port_t
+is returned specifying the bitmask of
+.Tn TCP
+ports that can only be bound by processes with root euid.
+When running with a
+.Xr securelevel 7
+greater than 0, this variable may not be changed.
.It Li udp.baddynamic
Analogous to
.Li tcp.baddynamic
@@ -1641,6 +1652,12 @@ Returns the default
send buffer size.
.It Li udp.stats
Returns the UDP statistics in a struct udpstat.
+.It Li udp.rootonly
+Analogous to
+.Li tcp.rootonly
+but for
+.Tn UDP
+sockets.
.El
.It Dv PF_INET6
Get or set various global information about IPv6
diff --git a/sbin/sysctl/sysctl.8 b/sbin/sysctl/sysctl.8
index 62944568169..682837c8907 100644
--- a/sbin/sysctl/sysctl.8
+++ b/sbin/sysctl/sysctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sysctl.8,v 1.198 2016/06/07 05:52:49 tim Exp $
+.\" $OpenBSD: sysctl.8,v 1.199 2016/06/18 10:36:13 vgross Exp $
.\" $NetBSD: sysctl.8,v 1.4 1995/09/30 07:12:49 thorpej Exp $
.\"
.\" Copyright (c) 1993
@@ -30,7 +30,7 @@
.\"
.\" @(#)sysctl.8 8.2 (Berkeley) 5/9/95
.\"
-.Dd $Mdocdate: June 7 2016 $
+.Dd $Mdocdate: June 18 2016 $
.Dt SYSCTL 8
.Os
.Sh NAME
@@ -270,10 +270,12 @@ and a few require a kernel compiled with non-standard
.It net.inet.tcp.synuselimit Ta integer Ta yes
.It net.inet.tcp.rfc3390 Ta integer Ta yes
.It net.inet.tcp.reasslimit Ta integer Ta yes
+.It net.inet.tcp.rootonly Ta array Ta yes
.It net.inet.udp.checksum Ta integer Ta yes
.It net.inet.udp.baddynamic Ta array Ta yes
.It net.inet.udp.recvspace Ta integer Ta yes
.It net.inet.udp.sendspace Ta integer Ta yes
+.It net.inet.udp.rootonly Ta array Ta yes
.It net.inet.gre.allow Ta integer Ta yes
.It net.inet.gre.wccp Ta integer Ta yes
.It net.inet.esp.enable Ta integer Ta yes
diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c
index 72799f652d8..9132c587745 100644
--- a/sbin/sysctl/sysctl.c
+++ b/sbin/sysctl/sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysctl.c,v 1.214 2016/05/23 15:48:59 deraadt Exp $ */
+/* $OpenBSD: sysctl.c,v 1.215 2016/06/18 10:36:13 vgross Exp $ */
/* $NetBSD: sysctl.c,v 1.9 1995/09/30 07:12:50 thorpej Exp $ */
/*
@@ -545,9 +545,11 @@ parse(char *string, int flags)
string);
return;
} else if ((mib[2] == IPPROTO_TCP &&
- mib[3] == TCPCTL_BADDYNAMIC) ||
+ (mib[3] == TCPCTL_BADDYNAMIC ||
+ mib[3] == TCPCTL_ROOTONLY)) ||
(mib[2] == IPPROTO_UDP &&
- mib[3] == UDPCTL_BADDYNAMIC)) {
+ (mib[3] == UDPCTL_BADDYNAMIC ||
+ mib[3] == UDPCTL_ROOTONLY))) {
special |= BADDYNAMIC;
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 44d08eaab39..5cf54ac7550 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_pcb.c,v 1.206 2016/04/19 22:16:25 sthen Exp $ */
+/* $OpenBSD: in_pcb.c,v 1.207 2016/06/18 10:36:13 vgross Exp $ */
/* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */
/*
@@ -121,6 +121,7 @@ int ipport_hifirstauto = IPPORT_HIFIRSTAUTO;
int ipport_hilastauto = IPPORT_HILASTAUTO;
struct baddynamicports baddynamicports;
+struct baddynamicports rootonlyports;
struct pool inpcb_pool;
int inpcb_pool_initialized = 0;
@@ -230,6 +231,21 @@ in_baddynamic(u_int16_t port, u_int16_t proto)
}
int
+in_rootonly(u_int16_t port, u_int16_t proto)
+{
+ switch (proto) {
+ case IPPROTO_TCP:
+ return (port < IPPORT_RESERVED ||
+ DP_ISSET(rootonlyports.tcp, port));
+ case IPPROTO_UDP:
+ return (port < IPPORT_RESERVED ||
+ DP_ISSET(rootonlyports.udp, port));
+ default:
+ return (0);
+ }
+}
+
+int
in_pcballoc(struct socket *so, struct inpcbtable *table)
{
struct inpcb *inp;
@@ -347,7 +363,8 @@ in_pcbbind(struct inpcb *inp, struct mbuf *nam, struct proc *p)
if ((error = in_pcbpickport(&lport, laddr, wild, inp, p)))
return (error);
} else {
- if (ntohs(lport) < IPPORT_RESERVED && (error = suser(p, 0)))
+ if (in_rootonly(ntohs(lport), so->so_proto->pr_protocol) &&
+ suser(p, 0) != 0)
return (EACCES);
}
if (nam) {
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index c695533d0ab..cdf3393c2fa 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_pcb.h,v 1.98 2016/04/11 21:24:29 vgross Exp $ */
+/* $OpenBSD: in_pcb.h,v 1.99 2016/06/18 10:36:13 vgross Exp $ */
/* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */
/*
@@ -230,6 +230,13 @@ struct inpcbtable {
0 }
#define DEFBADDYNAMICPORTS_UDP { 623, 664, 749, 750, 751, 2049, 0 }
+#define DEFROOTONLYPORTS_TCP { \
+ 2049, \
+ 0 }
+#define DEFROOTONLYPORTS_UDP { \
+ 2049, \
+ 0 }
+
struct baddynamicports {
u_int32_t tcp[DP_MAPSIZE];
u_int32_t udp[DP_MAPSIZE];
@@ -238,6 +245,7 @@ struct baddynamicports {
#ifdef _KERNEL
extern struct baddynamicports baddynamicports;
+extern struct baddynamicports rootonlyports;
#define sotopf(so) (so->so_proto->pr_domain->dom_family)
@@ -279,6 +287,7 @@ void in_rtchange(struct inpcb *, int);
void in_setpeeraddr(struct inpcb *, struct mbuf *);
void in_setsockaddr(struct inpcb *, struct mbuf *);
int in_baddynamic(u_int16_t, u_int16_t);
+int in_rootonly(u_int16_t, u_int16_t);
int in_selectsrc(struct in_addr **, struct sockaddr_in *,
struct ip_moptions *, struct route *, struct in_addr *, u_int);
struct rtentry *
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 332060c7988..432ca7866d0 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.276 2016/05/07 09:56:39 mpi Exp $ */
+/* $OpenBSD: ip_input.c,v 1.277 2016/06/18 10:36:13 vgross Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -163,6 +163,8 @@ ip_init(void)
int i;
const u_int16_t defbaddynamicports_tcp[] = DEFBADDYNAMICPORTS_TCP;
const u_int16_t defbaddynamicports_udp[] = DEFBADDYNAMICPORTS_UDP;
+ const u_int16_t defrootonlyports_tcp[] = DEFROOTONLYPORTS_TCP;
+ const u_int16_t defrootonlyports_udp[] = DEFROOTONLYPORTS_UDP;
pool_init(&ipqent_pool, sizeof(struct ipqent), 0, 0, 0, "ipqe", NULL);
pool_init(&ipq_pool, sizeof(struct ipq), 0, 0, 0, "ipq", NULL);
@@ -190,6 +192,13 @@ ip_init(void)
for (i = 0; defbaddynamicports_udp[i] != 0; i++)
DP_SET(baddynamicports.udp, defbaddynamicports_udp[i]);
+ /* Fill in list of ports only root can bind to. */
+ memset(&rootonlyports, 0, sizeof(rootonlyports));
+ for (i = 0; defrootonlyports_tcp[i] != 0; i++)
+ DP_SET(rootonlyports.tcp, defrootonlyports_tcp[i]);
+ for (i = 0; defrootonlyports_udp[i] != 0; i++)
+ DP_SET(rootonlyports.udp, defrootonlyports_udp[i]);
+
strlcpy(ipsec_def_enc, IPSEC_DEFAULT_DEF_ENC, sizeof(ipsec_def_enc));
strlcpy(ipsec_def_auth, IPSEC_DEFAULT_DEF_AUTH, sizeof(ipsec_def_auth));
strlcpy(ipsec_def_comp, IPSEC_DEFAULT_DEF_COMP, sizeof(ipsec_def_comp));
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 1cb805eb715..964e330b405 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_usrreq.c,v 1.130 2016/03/29 18:13:20 bluhm Exp $ */
+/* $OpenBSD: tcp_usrreq.c,v 1.131 2016/06/18 10:36:13 vgross Exp $ */
/* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */
/*
@@ -885,6 +885,12 @@ tcp_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
return (sysctl_struct(oldp, oldlenp, newp, newlen,
baddynamicports.tcp, sizeof(baddynamicports.tcp)));
+ case TCPCTL_ROOTONLY:
+ if (newp && securelevel > 0)
+ return (EPERM);
+ return (sysctl_struct(oldp, oldlenp, newp, newlen,
+ rootonlyports.tcp, sizeof(rootonlyports.tcp)));
+
case TCPCTL_IDENT:
return (tcp_ident(oldp, oldlenp, newp, newlen, 0));
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index b99ba8a5cde..e057c084437 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_var.h,v 1.112 2016/03/29 18:13:20 bluhm Exp $ */
+/* $OpenBSD: tcp_var.h,v 1.113 2016/06/18 10:36:13 vgross Exp $ */
/* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */
/*
@@ -490,7 +490,8 @@ struct tcpstat {
#define TCPCTL_STATS 21 /* TCP statistics */
#define TCPCTL_ALWAYS_KEEPALIVE 22 /* assume SO_KEEPALIVE is always set */
#define TCPCTL_SYN_USE_LIMIT 23 /* number of uses before reseeding hash */
-#define TCPCTL_MAXID 24
+#define TCPCTL_ROOTONLY 24 /* return root only port bitmap */
+#define TCPCTL_MAXID 25
#define TCPCTL_NAMES { \
{ 0, 0 }, \
@@ -517,6 +518,7 @@ struct tcpstat {
{ "stats", CTLTYPE_STRUCT }, \
{ "always_keepalive", CTLTYPE_INT }, \
{ "synuselimit", CTLTYPE_INT }, \
+ { "rootonly", CTLTYPE_STRUCT }, \
}
#define TCPCTL_VARS { \
@@ -543,6 +545,7 @@ struct tcpstat {
NULL, \
NULL, \
NULL, \
+ NULL, \
NULL \
}
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index d5fa4165098..fb64c11dc4e 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_usrreq.c,v 1.212 2016/06/15 16:06:35 vgross Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.213 2016/06/18 10:36:13 vgross Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
@@ -1276,6 +1276,12 @@ udp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
return (sysctl_struct(oldp, oldlenp, newp, newlen,
baddynamicports.udp, sizeof(baddynamicports.udp)));
+ case UDPCTL_ROOTONLY:
+ if (newp && securelevel > 0)
+ return (EPERM);
+ return (sysctl_struct(oldp, oldlenp, newp, newlen,
+ rootonlyports.udp, sizeof(rootonlyports.udp)));
+
case UDPCTL_STATS:
if (newp != NULL)
return (EPERM);
diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h
index cfbf5152230..0473df1bc28 100644
--- a/sys/netinet/udp_var.h
+++ b/sys/netinet/udp_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_var.h,v 1.26 2014/04/23 12:25:35 mpi Exp $ */
+/* $OpenBSD: udp_var.h,v 1.27 2016/06/18 10:36:13 vgross Exp $ */
/* $NetBSD: udp_var.h,v 1.12 1996/02/13 23:44:41 christos Exp $ */
/*
@@ -78,7 +78,8 @@ struct udpstat {
#define UDPCTL_RECVSPACE 3 /* receive buffer space */
#define UDPCTL_SENDSPACE 4 /* send buffer space */
#define UDPCTL_STATS 5 /* UDP statistics */
-#define UDPCTL_MAXID 6
+#define UDPCTL_ROOTONLY 6 /* root only port bitmap */
+#define UDPCTL_MAXID 7
#define UDPCTL_NAMES { \
{ 0, 0 }, \
@@ -86,7 +87,8 @@ struct udpstat {
{ "baddynamic", CTLTYPE_STRUCT }, \
{ "recvspace", CTLTYPE_INT }, \
{ "sendspace", CTLTYPE_INT }, \
- { "stats", CTLTYPE_STRUCT } \
+ { "stats", CTLTYPE_STRUCT }, \
+ { "rootonly", CTLTYPE_STRUCT }, \
}
#define UDPCTL_VARS { \
@@ -95,6 +97,7 @@ struct udpstat {
NULL, \
&udp_recvspace, \
&udp_sendspace, \
+ NULL, \
NULL \
}