summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2024-03-22 07:15:05 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2024-03-22 07:15:05 +0000
commite1c409490b89b2618370aea810a2e84a3ccd07ba (patch)
tree1b1d39f8c4d5f28c0da983fd68f77013079ea8dd
parentdf71d3fbbc1305f3b0e5cdb02b99b9af8bc4e43c (diff)
Limit NFS connections to originate from a reserved port.
For TCP connections do the check when adding the socket via nfssvc(2). For UDP do the check early after soreceive(). On top of this limit the sockets added via nfssvc(2) to IPv4 TCP and UDP sockets. OK millert@ deraadt@
-rw-r--r--sys/nfs/nfs_socket.c23
-rw-r--r--sys/nfs/nfs_syscalls.c23
2 files changed, 39 insertions, 7 deletions
diff --git a/sys/nfs/nfs_socket.c b/sys/nfs/nfs_socket.c
index 26adde1a849..1743a0e556a 100644
--- a/sys/nfs/nfs_socket.c
+++ b/sys/nfs/nfs_socket.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_socket.c,v 1.145 2024/02/05 20:21:39 mvs Exp $ */
+/* $OpenBSD: nfs_socket.c,v 1.146 2024/03/22 07:15:04 claudio Exp $ */
/* $NetBSD: nfs_socket.c,v 1.27 1996/04/15 20:20:00 thorpej Exp $ */
/*
@@ -1624,11 +1624,22 @@ nfsrv_rcv(struct socket *so, caddr_t arg, int waitflag)
error = soreceive(so, &nam, &auio, &mp,
NULL, &flags, 0);
if (mp) {
- if (nam) {
- m = nam;
- m->m_next = mp;
- } else
- m = mp;
+ struct sockaddr_in *sin;
+
+ if (nam == NULL) {
+ nfsstats.srv_errs++;
+ m_freem(mp);
+ continue;
+ }
+ if (in_nam2sin(nam, &sin) != 0 ||
+ ntohs(sin->sin_port) >= IPPORT_RESERVED) {
+ nfsstats.srv_errs++;
+ m_freem(nam);
+ m_freem(mp);
+ continue;
+ }
+ m = nam;
+ m->m_next = mp;
if (slp->ns_recend)
slp->ns_recend->m_nextpkt = m;
else
diff --git a/sys/nfs/nfs_syscalls.c b/sys/nfs/nfs_syscalls.c
index 67539ec23bf..f3ccd3f5c16 100644
--- a/sys/nfs/nfs_syscalls.c
+++ b/sys/nfs/nfs_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_syscalls.c,v 1.121 2024/02/05 20:21:39 mvs Exp $ */
+/* $OpenBSD: nfs_syscalls.c,v 1.122 2024/03/22 07:15:04 claudio Exp $ */
/* $NetBSD: nfs_syscalls.c,v 1.19 1996/02/18 11:53:52 fvdl Exp $ */
/*
@@ -243,6 +243,27 @@ nfssvc_addsock(struct file *fp, struct mbuf *mynam)
return (EPERM);
}
}
+ /*
+ * Allow only IPv4 UDP and TCP sockets.
+ */
+ if ((so->so_type != SOCK_STREAM && so->so_type != SOCK_DGRAM) ||
+ so->so_proto->pr_domain->dom_family != AF_INET) {
+ m_freem(mynam);
+ return (EINVAL);
+ }
+ if (mynam != NULL) {
+ struct sockaddr_in *sin;
+ error = in_nam2sin(mynam, &sin);
+ if (error) {
+ m_freem(mynam);
+ return (error);
+ }
+ if (ntohs(sin->sin_port) >= IPPORT_RESERVED) {
+ m_freem(mynam);
+ return (ECONNREFUSED);
+ }
+ }
+
if (so->so_type == SOCK_STREAM)
siz = NFS_MAXPACKET + sizeof (u_long);
else