Use the remote address for access control, not the local address. This fixes

the nfsd problems that some people have with the new code.

Add support for the vfs.nfsrv.nfs_privport sysctl which denies access unless
the client is using a port number less than 1024. Not really sure if this is
particularly useful since it doesn't add any real security.
This commit is contained in:
Doug Rabson 2008-11-13 14:36:52 +00:00
parent 0eec5c87bf
commit 36b83ac1b0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=184921
2 changed files with 45 additions and 2 deletions

View File

@ -348,19 +348,61 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
nfs_realign(&mreq);
/*
* Note: we want rq_addr, not svc_getrpccaller -
* Note: we want rq_addr, not svc_getrpccaller for nd_nam2 -
* NFS_SRVMAXDATA uses a NULL value for nd_nam2 to detect TCP
* mounts.
*/
memset(&nd, 0, sizeof(nd));
nd.nd_md = nd.nd_mrep = mreq;
nd.nd_dpos = mtod(mreq, caddr_t);
nd.nd_nam = (struct sockaddr *) &xprt->xp_ltaddr;
nd.nd_nam = svc_getrpccaller(rqst);
nd.nd_nam2 = rqst->rq_addr;
nd.nd_procnum = procnum;
nd.nd_cr = NULL;
nd.nd_flag = flag;
if (nfs_privport) {
/* Check if source port is privileged */
u_short port;
struct sockaddr *nam = nd.nd_nam;
struct sockaddr_in *sin;
sin = (struct sockaddr_in *)nam;
/*
* INET/INET6 - same code:
* sin_port and sin6_port are at same offset
*/
port = ntohs(sin->sin_port);
if (port >= IPPORT_RESERVED &&
nd.nd_procnum != NFSPROC_NULL) {
#ifdef INET6
char b6[INET6_ADDRSTRLEN];
#if defined(KLD_MODULE)
/* Do not use ip6_sprintf: the nfs module should work without INET6. */
#define ip6_sprintf(buf, a) \
(sprintf((buf), "%x:%x:%x:%x:%x:%x:%x:%x", \
(a)->s6_addr16[0], (a)->s6_addr16[1], \
(a)->s6_addr16[2], (a)->s6_addr16[3], \
(a)->s6_addr16[4], (a)->s6_addr16[5], \
(a)->s6_addr16[6], (a)->s6_addr16[7]), \
(buf))
#endif
#endif
printf("NFS request from unprivileged port (%s:%d)\n",
#ifdef INET6
sin->sin_family == AF_INET6 ?
ip6_sprintf(b6, &satosin6(sin)->sin6_addr) :
#if defined(KLD_MODULE)
#undef ip6_sprintf
#endif
#endif
inet_ntoa(sin->sin_addr), port);
svcerr_weakauth(rqst);
svc_freereq(rqst);
return;
}
}
if (proc != nfsrv_null) {
if (!svc_getcred(rqst, &nd.nd_cr, &nd.nd_credflavor)) {
svcerr_weakauth(rqst);

View File

@ -65,6 +65,7 @@ void
xdrmbuf_create(XDR *xdrs, struct mbuf *m, enum xdr_op op)
{
KASSERT(m != NULL, ("xdrmbuf_create with NULL mbuf chain"));
xdrs->x_op = op;
xdrs->x_ops = &xdrmbuf_ops;
xdrs->x_base = (char *) m;