diff options
-rw-r--r-- | sys/nfsclient/nfs_bio.c | 8 | ||||
-rw-r--r-- | sys/nfsclient/nfs_vfsops.c | 5 | ||||
-rw-r--r-- | sys/nfsclient/nfs_vnops.c | 8 |
3 files changed, 14 insertions, 7 deletions
diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index da8a2ec..305c189 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -445,6 +445,7 @@ nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) struct thread *td; struct nfsmount *nmp = VFSTONFS(vp->v_mount); daddr_t lbn, rabn; + off_t end; int bcount; int seqcount; int nra, error = 0, n = 0, on = 0; @@ -464,8 +465,9 @@ nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) } else mtx_unlock(&nmp->nm_mtx); + end = uio->uio_offset + uio->uio_resid; if (vp->v_type != VDIR && - (uio->uio_offset + uio->uio_resid) > nmp->nm_maxfilesize) + (end > nmp->nm_maxfilesize || end < uio->uio_offset)) return (EFBIG); if (nfs_directio_enable && (ioflag & IO_DIRECT) && (vp->v_type == VREG)) @@ -865,6 +867,7 @@ nfs_write(struct vop_write_args *ap) struct vattr vattr; struct nfsmount *nmp = VFSTONFS(vp->v_mount); daddr_t lbn; + off_t end; int bcount; int n, on, error = 0; @@ -932,7 +935,8 @@ flush_and_restart: if (uio->uio_offset < 0) return (EINVAL); - if ((uio->uio_offset + uio->uio_resid) > nmp->nm_maxfilesize) + end = uio->uio_offset + uio->uio_resid; + if (end > nmp->nm_maxfilesize || end < uio->uio_offset) return (EFBIG); if (uio->uio_resid == 0) return (0); diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c index 8498ee4..6bcc9b5 100644 --- a/sys/nfsclient/nfs_vfsops.c +++ b/sys/nfsclient/nfs_vfsops.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include <sys/bio.h> #include <sys/buf.h> #include <sys/jail.h> +#include <sys/limits.h> #include <sys/lock.h> #include <sys/malloc.h> #include <sys/mbuf.h> @@ -1228,13 +1229,11 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, * * For V3, nfs_fsinfo will adjust this as necessary. Assume maximum * that we can handle until we find out otherwise. - * XXX Our "safe" limit on the client is what we can store in our - * buffer cache using signed(!) block numbers. */ if ((argp->flags & NFSMNT_NFSV3) == 0) nmp->nm_maxfilesize = 0xffffffffLL; else - nmp->nm_maxfilesize = (u_int64_t)0x80000000 * DEV_BSIZE - 1; + nmp->nm_maxfilesize = OFF_MAX; nmp->nm_timeo = NFS_TIMEO; nmp->nm_retry = NFS_RETRANS; diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index bb81f6b..a9f746d 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -1276,6 +1276,7 @@ nfs_readrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) caddr_t bpos, dpos; struct mbuf *mreq, *mrep, *md, *mb; struct nfsmount *nmp; + off_t end; int error = 0, len, retlen, tsiz, eof, attrflag; int v3 = NFS_ISV3(vp); int rsize; @@ -1286,7 +1287,8 @@ nfs_readrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) nmp = VFSTONFS(vp->v_mount); tsiz = uiop->uio_resid; mtx_lock(&nmp->nm_mtx); - if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize) { + end = uiop->uio_offset + tsiz; + if (end > nmp->nm_maxfilesize || end < uiop->uio_offset) { mtx_unlock(&nmp->nm_mtx); return (EFBIG); } @@ -1348,6 +1350,7 @@ nfs_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, caddr_t bpos, dpos; struct mbuf *mreq, *mrep, *md, *mb; struct nfsmount *nmp = VFSTONFS(vp->v_mount); + off_t end; int error = 0, len, tsiz, wccflag = NFSV3_WCCRATTR, rlen, commit; int v3 = NFS_ISV3(vp), committed = NFSV3WRITE_FILESYNC; int wsize; @@ -1356,7 +1359,8 @@ nfs_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, *must_commit = 0; tsiz = uiop->uio_resid; mtx_lock(&nmp->nm_mtx); - if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize) { + end = uiop->uio_offset + tsiz; + if (end > nmp->nm_maxfilesize || end < uiop->uio_offset) { mtx_unlock(&nmp->nm_mtx); return (EFBIG); } |