From owner-svn-src-all@FreeBSD.ORG Thu May 21 23:14:19 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 23697B10; Thu, 21 May 2015 23:14:19 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 118C21641; Thu, 21 May 2015 23:14:19 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t4LNEIE2002651; Thu, 21 May 2015 23:14:18 GMT (envelope-from rmacklem@FreeBSD.org) Received: (from rmacklem@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t4LNEIvO002650; Thu, 21 May 2015 23:14:18 GMT (envelope-from rmacklem@FreeBSD.org) Message-Id: <201505212314.t4LNEIvO002650@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: rmacklem set sender to rmacklem@FreeBSD.org using -f From: Rick Macklem Date: Thu, 21 May 2015 23:14:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r283273 - head/sys/fs/nfsclient X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 21 May 2015 23:14:19 -0000 Author: rmacklem Date: Thu May 21 23:14:18 2015 New Revision: 283273 URL: https://svnweb.freebsd.org/changeset/base/283273 Log: The NFS client wasn't handling getdirentries(2) requests for sizes that are not an exact multiple of DIRBLKSIZ correctly. Fortunately readdir(3) always uses an exact multiple of DIRBLKSIZ, so few applications were affected. This patch fixes this problem by reducing the size of the directory read to an exact multiple of DIRBLKSIZ. Tested by: trasz Reported by: trasz Reviewed by: trasz MFC after: 2 weeks Modified: head/sys/fs/nfsclient/nfs_clvnops.c Modified: head/sys/fs/nfsclient/nfs_clvnops.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clvnops.c Thu May 21 22:50:39 2015 (r283272) +++ head/sys/fs/nfsclient/nfs_clvnops.c Thu May 21 23:14:18 2015 (r283273) @@ -2210,7 +2210,7 @@ nfs_readdir(struct vop_readdir_args *ap) struct vnode *vp = ap->a_vp; struct nfsnode *np = VTONFS(vp); struct uio *uio = ap->a_uio; - ssize_t tresid; + ssize_t tresid, left; int error = 0; struct vattr vattr; @@ -2239,6 +2239,17 @@ nfs_readdir(struct vop_readdir_args *ap) } /* + * NFS always guarantees that directory entries don't straddle + * DIRBLKSIZ boundaries. As such, we need to limit the size + * to an exact multiple of DIRBLKSIZ, to avoid copying a partial + * directory entry. + */ + left = uio->uio_resid % DIRBLKSIZ; + if (left == uio->uio_resid) + return (EINVAL); + uio->uio_resid -= left; + + /* * Call ncl_bioread() to do the real work. */ tresid = uio->uio_resid; @@ -2249,6 +2260,9 @@ nfs_readdir(struct vop_readdir_args *ap) if (ap->a_eofflag != NULL) *ap->a_eofflag = 1; } + + /* Add the partial DIRBLKSIZ (left) back in. */ + uio->uio_resid += left; return (error); }