Author: rmacklem
Date: Tue Apr  6 01:14:49 2010
New Revision: 206236
URL: http://svn.freebsd.org/changeset/base/206236

Log:
  Harden the experimental NFS server a little, by adding range
  checks on the length of the client's open/lock owner name. Also,
  add free()'s for one case where they were missing and would
  have caused a leak if NFSERR_BADXDR had been replied. Probably
  never happens, but the leak is now plugged, just in case.
  
  MFC after:    2 weeks

Modified:
  head/sys/fs/nfsserver/nfs_nfsdserv.c

Modified: head/sys/fs/nfsserver/nfs_nfsdserv.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdserv.c        Tue Apr  6 01:13:29 2010        
(r206235)
+++ head/sys/fs/nfsserver/nfs_nfsdserv.c        Tue Apr  6 01:14:49 2010        
(r206236)
@@ -2086,6 +2086,10 @@ nfsrvd_lock(struct nfsrv_descript *nd, _
        if (flags & NFSLCK_OPENTOLOCK) {
                NFSM_DISSECT(tl, u_int32_t *, 5 * NFSX_UNSIGNED + NFSX_STATEID);
                i = fxdr_unsigned(int, *(tl+4+(NFSX_STATEID / NFSX_UNSIGNED)));
+               if (i <= 0 || i > NFSV4_OPAQUELIMIT) {
+                       nd->nd_repstat = NFSERR_BADXDR;
+                       goto nfsmout;
+               }
                MALLOC(stp, struct nfsstate *, sizeof (struct nfsstate) + i,
                        M_NFSDSTATE, M_WAITOK);
                stp->ls_ownerlen = i;
@@ -2229,6 +2233,10 @@ nfsrvd_lockt(struct nfsrv_descript *nd, 
 
        NFSM_DISSECT(tl, u_int32_t *, 8 * NFSX_UNSIGNED);
        i = fxdr_unsigned(int, *(tl + 7));
+       if (i <= 0 || i > NFSV4_OPAQUELIMIT) {
+               nd->nd_repstat = NFSERR_BADXDR;
+               goto nfsmout;
+       }
        MALLOC(stp, struct nfsstate *, sizeof (struct nfsstate) + i,
            M_NFSDSTATE, M_WAITOK);
        stp->ls_ownerlen = i;
@@ -2350,6 +2358,8 @@ nfsrvd_locku(struct nfsrv_descript *nd, 
                break;
        default:
                nd->nd_repstat = NFSERR_BADXDR;
+               free(stp, M_NFSDSTATE);
+               free(lop, M_NFSDLOCK);
                goto nfsmout;
        };
        stp->ls_ownerlen = 0;
@@ -2439,6 +2449,14 @@ nfsrvd_open(struct nfsrv_descript *nd, _
        named.ni_cnd.cn_nameiop = 0;
        NFSM_DISSECT(tl, u_int32_t *, 6 * NFSX_UNSIGNED);
        i = fxdr_unsigned(int, *(tl + 5));
+       if (i <= 0 || i > NFSV4_OPAQUELIMIT) {
+               nd->nd_repstat = NFSERR_BADXDR;
+               vrele(dp);
+#ifdef NFS4_ACL_EXTATTR_NAME
+               acl_free(aclp);
+#endif
+               return (0);
+       }
        MALLOC(stp, struct nfsstate *, sizeof (struct nfsstate) + i,
            M_NFSDSTATE, M_WAITOK);
        stp->ls_ownerlen = i;
@@ -3391,6 +3409,10 @@ nfsrvd_releaselckown(struct nfsrv_descri
        }
        NFSM_DISSECT(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
        len = fxdr_unsigned(int, *(tl + 2));
+       if (len <= 0 || len > NFSV4_OPAQUELIMIT) {
+               nd->nd_repstat = NFSERR_BADXDR;
+               return (0);
+       }
        MALLOC(stp, struct nfsstate *, sizeof (struct nfsstate) + len,
            M_NFSDSTATE, M_WAITOK);
        stp->ls_ownerlen = len;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to