Skip to content

Commit

Permalink
nfs: Permit null requests (aka server pings) from non-reserved ports
Browse files Browse the repository at this point in the history
Unfortunately, this is recommended by rfc 2623 and used by Linux
nfs-utils to mount NFS exports. So until nfs-utils switches into
using reserved ports, this is needed to mount OpenBSD file-systems
on most (all?) Linux distros.

Bits from claudio, ok millert
  • Loading branch information
ratchov committed Apr 19, 2024
1 parent 16245c6 commit 9ca5b5e
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 29 deletions.
18 changes: 2 additions & 16 deletions sys/nfs/nfs_socket.c
@@ -1,4 +1,4 @@
/* $OpenBSD: nfs_socket.c,v 1.147 2024/03/31 13:50:00 mvs Exp $ */
/* $OpenBSD: nfs_socket.c,v 1.148 2024/04/19 06:50:37 ratchov Exp $ */
/* $NetBSD: nfs_socket.c,v 1.27 1996/04/15 20:20:00 thorpej Exp $ */

/*
Expand Down Expand Up @@ -1588,7 +1588,7 @@ nfsrv_rcv(struct socket *so, caddr_t arg, int waitflag)
*/
auio.uio_resid = 1000000000;
flags = MSG_DONTWAIT;
error = soreceive(so, &nam, &auio, &mp, NULL,
error = soreceive(so, NULL, &auio, &mp, NULL,
&flags, 0);
if (error || mp == NULL) {
if (error == EWOULDBLOCK)
Expand Down Expand Up @@ -1626,20 +1626,6 @@ nfsrv_rcv(struct socket *so, caddr_t arg, int waitflag)
error = soreceive(so, &nam, &auio, &mp,
NULL, &flags, 0);
if (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)
Expand Down
36 changes: 23 additions & 13 deletions sys/nfs/nfs_syscalls.c
@@ -1,4 +1,4 @@
/* $OpenBSD: nfs_syscalls.c,v 1.123 2024/03/31 13:50:00 mvs Exp $ */
/* $OpenBSD: nfs_syscalls.c,v 1.124 2024/04/19 06:50:37 ratchov Exp $ */
/* $NetBSD: nfs_syscalls.c,v 1.19 1996/02/18 11:53:52 fvdl Exp $ */

/*
Expand Down Expand Up @@ -251,18 +251,6 @@ nfssvc_addsock(struct file *fp, struct mbuf *mynam)
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);
Expand Down Expand Up @@ -323,6 +311,18 @@ nfssvc_addsock(struct file *fp, struct mbuf *mynam)
return (0);
}

static inline int nfssvc_checknam(struct mbuf *nam)
{
struct sockaddr_in *sin;

if (nam == NULL ||
in_nam2sin(nam, &sin) != 0 ||
ntohs(sin->sin_port) >= IPPORT_RESERVED) {
return -1;
}
return 0;
}

/*
* Called by nfssvc() for nfsds. Just loops around servicing rpc requests
* until it is killed by a signal.
Expand Down Expand Up @@ -402,6 +402,16 @@ nfssvc_nfsd(struct nfsd *nfsd)
cacherep = nfsrv_getcache(nd, slp, &mreq);
switch (cacherep) {
case RC_DOIT:
/*
* Unless this is a null request (server ping), make
* sure that the client is using a reserved source port.
*/
if (nd->nd_procnum != 0 && nfssvc_checknam(nd->nd_nam) == -1) {
/* drop it */
m_freem(nd->nd_mrep);
m_freem(nd->nd_nam2);
break;
}
error = (*(nfsrv3_procs[nd->nd_procnum]))(nd, slp, nfsd->nfsd_procp, &mreq);
if (mreq == NULL) {
if (nd != NULL) {
Expand Down

0 comments on commit 9ca5b5e

Please sign in to comment.