Author: rmacklem
Date: Wed Apr 20 01:15:22 2011
New Revision: 220877
URL: http://svn.freebsd.org/changeset/base/220877

Log:
  Modify the offset + size checks for read and write in the
  experimental NFS client to take care of overflows for the calls
  above the buffer cache layer in a manner similar to r220876.
  Thanks go to dillon at apollo.backplane.com for providing the
  snippet of code that does this.
  
  MFC after:    2 weeks

Modified:
  head/sys/fs/nfsclient/nfs_clbio.c

Modified: head/sys/fs/nfsclient/nfs_clbio.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clbio.c   Wed Apr 20 00:21:51 2011        
(r220876)
+++ head/sys/fs/nfsclient/nfs_clbio.c   Wed Apr 20 01:15:22 2011        
(r220877)
@@ -452,6 +452,7 @@ ncl_bioread(struct vnode *vp, struct uio
        int bcount;
        int seqcount;
        int nra, error = 0, n = 0, on = 0;
+       off_t tmp_off;
 
        KASSERT(uio->uio_rw == UIO_READ, ("ncl_read mode"));
        if (uio->uio_resid == 0)
@@ -469,11 +470,14 @@ ncl_bioread(struct vnode *vp, struct uio
        }
        if (nmp->nm_rsize == 0 || nmp->nm_readdirsize == 0)
                (void) newnfs_iosize(nmp);
-       mtx_unlock(&nmp->nm_mtx);               
 
+       tmp_off = uio->uio_offset + uio->uio_resid;
        if (vp->v_type != VDIR &&
-           (uio->uio_offset + uio->uio_resid) > nmp->nm_maxfilesize)
+           (tmp_off > nmp->nm_maxfilesize || tmp_off < uio->uio_offset)) {
+               mtx_unlock(&nmp->nm_mtx);               
                return (EFBIG);
+       }
+       mtx_unlock(&nmp->nm_mtx);               
 
        if (newnfs_directio_enable && (ioflag & IO_DIRECT) && (vp->v_type == 
VREG))
                /* No caching/ no readaheads. Just read data into the user 
buffer */
@@ -874,6 +878,7 @@ ncl_write(struct vop_write_args *ap)
        daddr_t lbn;
        int bcount;
        int n, on, error = 0;
+       off_t tmp_off;
 
        KASSERT(uio->uio_rw == UIO_WRITE, ("ncl_write mode"));
        KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread,
@@ -940,8 +945,13 @@ flush_and_restart:
 
        if (uio->uio_offset < 0)
                return (EINVAL);
-       if ((uio->uio_offset + uio->uio_resid) > nmp->nm_maxfilesize)
+       tmp_off = uio->uio_offset + uio->uio_resid;
+       mtx_lock(&nmp->nm_mtx);
+       if (tmp_off > nmp->nm_maxfilesize || tmp_off < uio->uio_offset) {
+               mtx_unlock(&nmp->nm_mtx);
                return (EFBIG);
+       }
+       mtx_unlock(&nmp->nm_mtx);
        if (uio->uio_resid == 0)
                return (0);
 
_______________________________________________
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