From: claudio Date: Fri, 22 Mar 2024 07:15:04 +0000 (+0000) Subject: Limit NFS connections to originate from a reserved port. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=a6ac7a8b64b691f0c7164abfad8061c6f87f7e30;p=openbsd 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@ --- 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