The NFS v2 internal server uses several validation checks for each
authorzoulasc <christos@zoulas.com>
Thu, 3 Mar 2016 18:29:52 +0000 (13:29 -0500)
committerzoulasc <christos@zoulas.com>
Thu, 3 Mar 2016 18:29:52 +0000 (13:29 -0500)
RPC request it receives, also add this validation for the NFS v3
internal server.

From Ian Kent

amd/nfs_prot_svc.c

index 29b7551babef8cff21b2d0b724aadbc3e07098f4..cae12d4691994ea008c89ba93332bcf9de97b639 100644 (file)
@@ -71,30 +71,9 @@ dispatcher_t nfs_dispatcher = nfs_program_2;
 typedef char *(*nfssvcproc_t)(voidp, struct svc_req *);
 
 
-void
-nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
+static int
+validate_rpc_request(struct svc_req *rqstp, SVCXPRT *transp)
 {
-  union {
-    am_nfs_fh          nfsproc_getattr_2_arg;
-    nfssattrargs       nfsproc_setattr_2_arg;
-    nfsdiropargs       nfsproc_lookup_2_arg;
-    am_nfs_fh          nfsproc_readlink_2_arg;
-    nfsreadargs                nfsproc_read_2_arg;
-    nfswriteargs       nfsproc_write_2_arg;
-    nfscreateargs      nfsproc_create_2_arg;
-    nfsdiropargs       nfsproc_remove_2_arg;
-    nfsrenameargs      nfsproc_rename_2_arg;
-    nfslinkargs                nfsproc_link_2_arg;
-    nfssymlinkargs     nfsproc_symlink_2_arg;
-    nfscreateargs      nfsproc_mkdir_2_arg;
-    nfsdiropargs       fsproc_rmdir_2_arg;
-    nfsreaddirargs     nfsproc_readdir_2_arg;
-    am_nfs_fh          nfsproc_statfs_2_arg;
-  } argument;
-  char *result;
-  xdrproc_t xdr_argument, xdr_result;
-  nfssvcproc_t local;
-
 #ifdef HAVE_TRANSPORT_TYPE_TLI
   /*
    * On TLI systems we don't use an INET network type, but a "ticlts" (see
@@ -109,7 +88,7 @@ nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
   extern int __rpc_get_local_uid(SVCXPRT *transp, uid_t *uid);
   if (__rpc_get_local_uid(transp, &u) >= 0  &&  u != 0) {
     plog(XLOG_WARNING, "ignoring request from UID %ld, must be 0", (long) u);
-    return;
+    return 0;
   }
 # else /* not HAVE___RPC_GET_LOCAL_UID */
   dlog("cannot verify local uid for rpc request");
@@ -126,7 +105,7 @@ nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
     plog(XLOG_WARNING, "ignoring request from %s:%u, port not reserved",
         inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
         ntohs(sinp->sin_port));
-    return;
+    return 0;
   }
 # endif /* MNT2_NFS_OPT_RESVPORT */
   /* if the address does not match, ignore the request */
@@ -136,16 +115,47 @@ nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
        plog(XLOG_WARNING, "ignoring request from %s:%u, not a local interface",
             inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
             ntohs(sinp->sin_port));
+             return 0;
       }
     } else {
       plog(XLOG_WARNING, "ignoring request from %s:%u, expected %s",
           inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
           ntohs(sinp->sin_port),
           inet_dquad(dq2, sizeof(dq2), myipaddr.s_addr));
-      return;
+      return 0;
     }
   }
 #endif /* not HAVE_TRANPORT_TYPE_TLI */
+  return 1;
+}
+
+
+void
+nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
+{
+  union {
+    am_nfs_fh          nfsproc_getattr_2_arg;
+    nfssattrargs       nfsproc_setattr_2_arg;
+    nfsdiropargs       nfsproc_lookup_2_arg;
+    am_nfs_fh          nfsproc_readlink_2_arg;
+    nfsreadargs                nfsproc_read_2_arg;
+    nfswriteargs       nfsproc_write_2_arg;
+    nfscreateargs      nfsproc_create_2_arg;
+    nfsdiropargs       nfsproc_remove_2_arg;
+    nfsrenameargs      nfsproc_rename_2_arg;
+    nfslinkargs                nfsproc_link_2_arg;
+    nfssymlinkargs     nfsproc_symlink_2_arg;
+    nfscreateargs      nfsproc_mkdir_2_arg;
+    nfsdiropargs       fsproc_rmdir_2_arg;
+    nfsreaddirargs     nfsproc_readdir_2_arg;
+    am_nfs_fh          nfsproc_statfs_2_arg;
+  } argument;
+  char *result;
+  xdrproc_t xdr_argument, xdr_result;
+  nfssvcproc_t local;
+
+  if (!validate_rpc_request(rqstp, transp))
+    return;
 
   current_transp = NULL;
 
@@ -327,6 +337,9 @@ nfs_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
   xdrproc_t _xdr_argument, _xdr_result;
   nfssvcproc_t local;
 
+  if (!validate_rpc_request(rqstp, transp))
+    return;
+
   current_transp = NULL;
 
   switch (rqstp->rq_proc) {