--- a/usr/src/uts/common/fs/nfs/nfs4_dispatch.c Wed Jul 11 16:37:00 2007 -0700
+++ b/usr/src/uts/common/fs/nfs/nfs4_dispatch.c Wed Jul 11 18:54:04 2007 -0700
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,6 +38,8 @@
#include <nfs/nfs_dispatch.h>
#include <nfs/nfs4_drc.h>
+#define NFS4_MAX_MINOR_VERSION 0
+
/*
* This is the duplicate request cache for NFSv4
*/
@@ -528,3 +530,38 @@
return (error);
}
+
+bool_t
+rfs4_minorvers_mismatch(struct svc_req *req, SVCXPRT *xprt, void *args)
+{
+ COMPOUND4args *argsp;
+ COMPOUND4res res_buf, *resp;
+
+ if (req->rq_vers != 4)
+ return (FALSE);
+
+ argsp = (COMPOUND4args *)args;
+
+ if (argsp->minorversion <= NFS4_MAX_MINOR_VERSION)
+ return (FALSE);
+
+ resp = &res_buf;
+
+ /*
+ * Form a reply tag by copying over the reqeuest tag.
+ */
+ resp->tag.utf8string_val =
+ kmem_alloc(argsp->tag.utf8string_len, KM_SLEEP);
+ resp->tag.utf8string_len = argsp->tag.utf8string_len;
+ bcopy(argsp->tag.utf8string_val, resp->tag.utf8string_val,
+ resp->tag.utf8string_len);
+ resp->array_len = 0;
+ resp->array = NULL;
+ resp->status = NFS4ERR_MINOR_VERS_MISMATCH;
+ if (!svc_sendreply(xprt, xdr_COMPOUND4res_srv, (char *)resp)) {
+ DTRACE_PROBE2(nfss__e__minorvers_mismatch,
+ SVCXPRT *, xprt, char *, resp);
+ }
+ rfs4_compound_free(resp);
+ return (TRUE);
+}
--- a/usr/src/uts/common/fs/nfs/nfs_server.c Wed Jul 11 16:37:00 2007 -0700
+++ b/usr/src/uts/common/fs/nfs/nfs_server.c Wed Jul 11 18:54:04 2007 -0700
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -259,6 +259,7 @@
nvlist_t *rfs4_dss_paths, *rfs4_dss_oldpaths;
int rfs4_dispatch(struct rpcdisp *, struct svc_req *, SVCXPRT *, char *);
+bool_t rfs4_minorvers_mismatch(struct svc_req *, SVCXPRT *, void *);
/*
* RDMA wait variables.
@@ -1481,8 +1482,14 @@
{
bzero(args, disp->dis_argsz);
if (!SVC_GETARGS(xprt, disp->dis_xdrargs, args)) {
+ error++;
+ /*
+ * Check if we are outside our capabilities.
+ */
+ if (rfs4_minorvers_mismatch(req, xprt, (void *)args))
+ goto done;
+
svcerr_decode(xprt);
- error++;
cmn_err(CE_NOTE,
"Failed to decode arguments for %s version %u "
"procedure %s client %s%s",