From owner-svn-src-head@freebsd.org Fri Nov 23 00:17:48 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3CE9E1135149; Fri, 23 Nov 2018 00:17:48 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id D667A6EBDD; Fri, 23 Nov 2018 00:17:47 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id B04EC170F9; Fri, 23 Nov 2018 00:17:47 +0000 (UTC) (envelope-from rmacklem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id wAN0HlwH021906; Fri, 23 Nov 2018 00:17:47 GMT (envelope-from rmacklem@FreeBSD.org) Received: (from rmacklem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id wAN0HlAe021905; Fri, 23 Nov 2018 00:17:47 GMT (envelope-from rmacklem@FreeBSD.org) Message-Id: <201811230017.wAN0HlAe021905@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: rmacklem set sender to rmacklem@FreeBSD.org using -f From: Rick Macklem Date: Fri, 23 Nov 2018 00:17:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r340787 - head/sys/fs/nfsclient X-SVN-Group: head X-SVN-Commit-Author: rmacklem X-SVN-Commit-Paths: head/sys/fs/nfsclient X-SVN-Commit-Revision: 340787 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: D667A6EBDD X-Spamd-Result: default: False [1.61 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_SPAM_SHORT(0.45)[0.452,0]; NEURAL_SPAM_MEDIUM(0.74)[0.738,0]; NEURAL_SPAM_LONG(0.42)[0.420,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US] X-Rspamd-Server: mx1.freebsd.org X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 Nov 2018 00:17:48 -0000 Author: rmacklem Date: Fri Nov 23 00:17:47 2018 New Revision: 340787 URL: https://svnweb.freebsd.org/changeset/base/340787 Log: Make sure the NFS readdir client fills in all "struct dirent" data. The NFS client code (nfsrpc_readdir() and nfsrpc_readdirplus()) wasn't filling in parts of the readdir reply, such as d_pad[01] and the bytes at the end of d_name within d_reclen. As such, data left in a buffer cache block could be leaked to userland in the readdir reply. This patch makes sure all of the data is filled in. Reported by: Thomas Barabosch, Fraunhofer FKIE Reviewed by: kib, markj MFC after: 2 weeks Modified: head/sys/fs/nfsclient/nfs_clrpcops.c Modified: head/sys/fs/nfsclient/nfs_clrpcops.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clrpcops.c Thu Nov 22 21:38:24 2018 (r340786) +++ head/sys/fs/nfsclient/nfs_clrpcops.c Fri Nov 23 00:17:47 2018 (r340787) @@ -2959,6 +2959,7 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 return (error); nd->nd_mrep = NULL; dp = (struct dirent *)uio_iov_base(uiop); + dp->d_pad0 = dp->d_pad1 = 0; dp->d_off = 0; dp->d_type = DT_DIR; dp->d_fileno = dotfileid; @@ -2978,6 +2979,7 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 uio_iov_base_add(uiop, dp->d_reclen); uio_iov_len_add(uiop, -(dp->d_reclen)); dp = (struct dirent *)uio_iov_base(uiop); + dp->d_pad0 = dp->d_pad1 = 0; dp->d_off = 0; dp->d_type = DT_DIR; dp->d_fileno = dotdotfileid; @@ -3091,6 +3093,7 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 tlen += 8; /* To ensure null termination. */ left = DIRBLKSIZ - blksiz; if (_GENERIC_DIRLEN(len) + NFSX_HYPER > left) { + NFSBZERO(uio_iov_base(uiop), left); dp->d_reclen += left; uio_iov_base_add(uiop, left); uio_iov_len_add(uiop, -(left)); @@ -3103,6 +3106,7 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 bigenough = 0; if (bigenough) { dp = (struct dirent *)uio_iov_base(uiop); + dp->d_pad0 = dp->d_pad1 = 0; dp->d_off = 0; dp->d_namlen = len; dp->d_reclen = _GENERIC_DIRLEN(len) + @@ -3120,7 +3124,7 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 goto nfsmout; cp = uio_iov_base(uiop); tlen -= len; - *cp = '\0'; /* null terminate */ + NFSBZERO(cp, tlen); cp += tlen; /* points to cookie storage */ tl2 = (u_int32_t *)cp; uio_iov_base_add(uiop, (tlen + NFSX_HYPER)); @@ -3208,6 +3212,7 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 */ if (blksiz > 0) { left = DIRBLKSIZ - blksiz; + NFSBZERO(uio_iov_base(uiop), left); dp->d_reclen += left; uio_iov_base_add(uiop, left); uio_iov_len_add(uiop, -(left)); @@ -3235,10 +3240,8 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 */ while (uio_uio_resid(uiop) > 0 && uio_uio_resid(uiop) != tresid) { dp = (struct dirent *)uio_iov_base(uiop); + NFSBZERO(dp, DIRBLKSIZ); dp->d_type = DT_UNKNOWN; - dp->d_fileno = 0; - dp->d_namlen = 0; - dp->d_name[0] = '\0'; tl = (u_int32_t *)&dp->d_name[4]; *tl++ = cookie.lval[0]; *tl = cookie.lval[1]; @@ -3393,6 +3396,7 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsui return (error); nd->nd_mrep = NULL; dp = (struct dirent *)uio_iov_base(uiop); + dp->d_pad0 = dp->d_pad1 = 0; dp->d_off = 0; dp->d_type = DT_DIR; dp->d_fileno = dotfileid; @@ -3412,6 +3416,7 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsui uio_iov_base_add(uiop, dp->d_reclen); uio_iov_len_add(uiop, -(dp->d_reclen)); dp = (struct dirent *)uio_iov_base(uiop); + dp->d_pad0 = dp->d_pad1 = 0; dp->d_off = 0; dp->d_type = DT_DIR; dp->d_fileno = dotdotfileid; @@ -3506,6 +3511,7 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsui tlen += 8; /* To ensure null termination. */ left = DIRBLKSIZ - blksiz; if (_GENERIC_DIRLEN(len) + NFSX_HYPER > left) { + NFSBZERO(uio_iov_base(uiop), left); dp->d_reclen += left; uio_iov_base_add(uiop, left); uio_iov_len_add(uiop, -(left)); @@ -3518,6 +3524,7 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsui bigenough = 0; if (bigenough) { dp = (struct dirent *)uio_iov_base(uiop); + dp->d_pad0 = dp->d_pad1 = 0; dp->d_off = 0; dp->d_namlen = len; dp->d_reclen = _GENERIC_DIRLEN(len) + @@ -3538,7 +3545,7 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsui goto nfsmout; cp = uio_iov_base(uiop); tlen -= len; - *cp = '\0'; + NFSBZERO(cp, tlen); cp += tlen; /* points to cookie storage */ tl2 = (u_int32_t *)cp; if (len == 2 && cnp->cn_nameptr[0] == '.' && @@ -3708,6 +3715,7 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsui */ if (blksiz > 0) { left = DIRBLKSIZ - blksiz; + NFSBZERO(uio_iov_base(uiop), left); dp->d_reclen += left; uio_iov_base_add(uiop, left); uio_iov_len_add(uiop, -(left)); @@ -3735,10 +3743,8 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsui */ while (uio_uio_resid(uiop) > 0 && uio_uio_resid(uiop) != tresid) { dp = (struct dirent *)uio_iov_base(uiop); + NFSBZERO(dp, DIRBLKSIZ); dp->d_type = DT_UNKNOWN; - dp->d_fileno = 0; - dp->d_namlen = 0; - dp->d_name[0] = '\0'; tl = (u_int32_t *)&dp->d_name[4]; *tl++ = cookie.lval[0]; *tl = cookie.lval[1];