From nobody Wed Mar 22 13:19:35 2023 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4PhTbD0RQbz40qc5; Wed, 22 Mar 2023 13:19:36 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4PhTbC6cyDz4WP8; Wed, 22 Mar 2023 13:19:35 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1679491175; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=lf3Kq0nP9YrkRwwEd030FWp6I4Z9hqzB44WK9iZC4xw=; b=mXUNJyOszlVLNSalJFAtSe5i9rcpNADv1HH4HmVbaK8juEmnkuHkosYacF2JFbGLGBL1FM KhsL6wJLY4epm9S9xnVVTPCjeCwlt+RqodcxHByomQ0WMwjiAFo3h1fhmMhVF54p5bE01h /HuGHQfjafO45KFxZECShh9oeUssosjFRkarWN5tL4KDTrw3HVc0Ex4HbmriBSVvD0OkGX 8j62Pn0xulU6YFqG7buPa5C0ZRt3U6IPdFdDCb+i9ad+S9q69c1JQ2j/gB4/haS/I/iAM0 x0ksebaGqqyMgnDw+9eGylayFHxSZ4qY60GMq32XCubLKbR/KY4lX8egRhqBWg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1679491175; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=lf3Kq0nP9YrkRwwEd030FWp6I4Z9hqzB44WK9iZC4xw=; b=aVbiFGPQcM7I76YeUxko2Bko3YVvLBVZAZVD3FuDiEYdsoXt9yiloYt27xSaDpaDXD5XZa k4q7EN2XYRKaYY1ZzyVNCHF/qbQpEUIv2QHA2T5d6EDuAAMDThPw3ccA6fYSGgdb9/ihwK 9CoAzxFqCvuMjxJ7KivUEv+pZjkJOc8fUK8k9ss8wd3zm8VknActQVk7lE2PiN+CGrbaU3 pl1HCjzxgUQL1xiDwi1SuNUh5ItD+RUNjrtZMwY1+1EO/h+DojSJbcqU76L+ULm634NB6Y 7ObipoxI4AeRLskPzj0EWrWKLk0hFZGptuS5I0tTZBhdFZd0QuOP3bVDBKh7TQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1679491175; a=rsa-sha256; cv=none; b=KNTmDaVPRHYaK73hizDLcEsTiyQHnqdVnO96LrFEQhyKMzyB0tq3ThCQc/txNd9nqBhU8T FBJlcboA3XpN9N1tXmQOphg3GwsaX/4Mrtsh4kF5VGMcC4BknWav4Np2gRVQM+lpuEpMxz muLg1j/XJ9S5/WAVJhuGNA1r+URMGvmr7Bd1Ztj6PksUf18TI33NWwvDMG9c0yiXBkkAXG i+RhGAeFVN+qWOYhjUc38XKj//m/TKvgGUdFAd+7z8v4SXOj9CMcjbS9g5Xi4dsHM0s9au wM0xIiuOeL7dRJ4Fxy7zIjAWLhl57OvfXxIAn04Qb9IY7J0YjQrjIBFz+359+g== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4PhTbC5fDMzvTv; Wed, 22 Mar 2023 13:19:35 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 32MDJZ0C097045; Wed, 22 Mar 2023 13:19:35 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 32MDJZ7T097041; Wed, 22 Mar 2023 13:19:35 GMT (envelope-from git) Date: Wed, 22 Mar 2023 13:19:35 GMT Message-Id: <202303221319.32MDJZ7T097041@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: 0f5b6f9a041e - main - fdescfs: Fix a file ref leak List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 0f5b6f9a041e9cca3b376f6ec909374938887a3b Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=0f5b6f9a041e9cca3b376f6ec909374938887a3b commit 0f5b6f9a041e9cca3b376f6ec909374938887a3b Author: Mark Johnston AuthorDate: 2023-03-22 12:52:57 +0000 Commit: Mark Johnston CommitDate: 2023-03-22 13:19:27 +0000 fdescfs: Fix a file ref leak In fdesc_lookup(), vn_vget_ino_gen() may fail without invoking the callback, in which case the ref on fp is leaked. This happens if the fdescfs mount is being concurrently unmounted. Moreover, we cannot safely drop the ref while the dvp is locked. So: - Use a flag variable to indicate whether the ref is dropped. - Reorganize things to handle the leak. Reported by: C Turt Reviewed by: mjg, kib Tested by: pho MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D39189 --- sys/fs/fdescfs/fdesc_vnops.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c index 0949dcc7eb29..d3c7951672cf 100644 --- a/sys/fs/fdescfs/fdesc_vnops.c +++ b/sys/fs/fdescfs/fdesc_vnops.c @@ -246,6 +246,7 @@ struct fdesc_get_ino_args { int ix; struct file *fp; struct thread *td; + bool fdropped; }; static int @@ -268,6 +269,7 @@ fdesc_get_ino_alloc(struct mount *mp, void *arg, int lkflags, error = fdesc_allocvp(a->ftype, a->fd_fd, a->ix, mp, rvp); } fdrop(a->fp, a->td); + a->fdropped = true; return (error); } @@ -288,6 +290,7 @@ fdesc_lookup(struct vop_lookup_args *ap) int nlen = cnp->cn_namelen; u_int fd, fd1; int error; + bool fdropped; struct vnode *fvp; if ((cnp->cn_flags & ISLASTCN) && @@ -331,24 +334,10 @@ fdesc_lookup(struct vop_lookup_args *ap) */ if ((error = fget(td, fd, &cap_no_rights, &fp)) != 0) goto bad; + fdropped = false; - /* Check if we're looking up ourselves. */ - if (VTOFDESC(dvp)->fd_ix == FD_DESC + fd) { - /* - * In case we're holding the last reference to the file, the dvp - * will be re-acquired. - */ - vhold(dvp); - VOP_UNLOCK(dvp); - fdrop(fp, td); - - /* Re-aquire the lock afterwards. */ - vn_lock(dvp, LK_RETRY | LK_EXCLUSIVE); - vdrop(dvp); - fvp = dvp; - if (VN_IS_DOOMED(dvp)) - error = ENOENT; - } else { + /* Make sure we're not looking up the dvp itself. */ + if (VTOFDESC(dvp)->fd_ix != FD_DESC + fd) { /* * Unlock our root node (dvp) when doing this, since we might * deadlock since the vnode might be locked by another thread @@ -362,8 +351,27 @@ fdesc_lookup(struct vop_lookup_args *ap) arg.ix = FD_DESC + fd; arg.fp = fp; arg.td = td; + arg.fdropped = fdropped; error = vn_vget_ino_gen(dvp, fdesc_get_ino_alloc, &arg, LK_EXCLUSIVE, &fvp); + fdropped = arg.fdropped; + } + + if (!fdropped) { + /* + * In case we're holding the last reference to the file, the dvp + * will be re-acquired. + */ + vhold(dvp); + VOP_UNLOCK(dvp); + fdrop(fp, td); + fdropped = true; + + vn_lock(dvp, LK_RETRY | LK_EXCLUSIVE); + vdrop(dvp); + fvp = dvp; + if (error == 0 && VN_IS_DOOMED(dvp)) + error = ENOENT; } if (error)