From owner-dev-commits-src-all@freebsd.org Sat May 22 20:14:23 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 1FA8F636CD3; Sat, 22 May 2021 20:14:23 +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 4FnZSb0PTSz3tT4; Sat, 22 May 2021 20:14:23 +0000 (UTC) (envelope-from git@FreeBSD.org) 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 DC25B23C7; Sat, 22 May 2021 20:14:22 +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 14MKEMQi053219; Sat, 22 May 2021 20:14:22 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 14MKEM0W053218; Sat, 22 May 2021 20:14:22 GMT (envelope-from git) Date: Sat, 22 May 2021 20:14:22 GMT Message-Id: <202105222014.14MKEM0W053218@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: fc369a353b5b - main - ktrace: fix a race between writes and close MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: fc369a353b5b5e0f8046687fcbd78a7cd9ad1810 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 22 May 2021 20:14:23 -0000 The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=fc369a353b5b5e0f8046687fcbd78a7cd9ad1810 commit fc369a353b5b5e0f8046687fcbd78a7cd9ad1810 Author: Konstantin Belousov AuthorDate: 2021-05-22 12:40:00 +0000 Commit: Konstantin Belousov CommitDate: 2021-05-22 20:14:13 +0000 ktrace: fix a race between writes and close It was possible that termination of ktrace session occured during some record write, in which case write occured after the close of the vnode. Use ktr_io_params refcounting to avoid this situation, by taking the reference on the structure instead of vnode. Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D30400 --- sys/kern/kern_ktrace.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index 875c079df3b9..3a223215a60d 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -1257,7 +1257,7 @@ ktrsetchildren(struct thread *td, struct proc *top, int ops, int facs, static void ktr_writerequest(struct thread *td, struct ktr_request *req) { - struct ktr_io_params *kiop; + struct ktr_io_params *kiop, *kiop1; struct ktr_header *kth; struct vnode *vp; struct proc *p; @@ -1272,14 +1272,10 @@ ktr_writerequest(struct thread *td, struct ktr_request *req) p = td->td_proc; /* - * We hold the vnode and credential for use in I/O in case ktrace is + * We reference the kiop for use in I/O in case ktrace is * disabled on the process as we write out the request. - * - * XXXRW: This is not ideal: we could end up performing a write after - * the vnode has been closed. */ mtx_lock(&ktrace_mtx); - kiop = p->p_ktrioparms; /* @@ -1291,13 +1287,12 @@ ktr_writerequest(struct thread *td, struct ktr_request *req) return; } + ktr_io_params_ref(kiop); vp = kiop->vp; cred = kiop->cr; lim = kiop->lim; - vrefact(vp); KASSERT(cred != NULL, ("ktr_writerequest: cred == NULL")); - crhold(cred); mtx_unlock(&ktrace_mtx); kth = &req->ktr_header; @@ -1339,9 +1334,11 @@ ktr_writerequest(struct thread *td, struct ktr_request *req) error = VOP_WRITE(vp, &auio, IO_UNIT | IO_APPEND, cred); VOP_UNLOCK(vp); vn_finished_write(mp); - crfree(cred); if (error == 0) { - vrele(vp); + mtx_lock(&ktrace_mtx); + kiop = ktr_io_params_rele(kiop); + mtx_unlock(&ktrace_mtx); + ktr_io_params_free(kiop); return; } @@ -1354,12 +1351,15 @@ ktr_writerequest(struct thread *td, struct ktr_request *req) "ktrace write failed, errno %d, tracing stopped for pid %d\n", error, p->p_pid); + kiop1 = NULL; PROC_LOCK(p); mtx_lock(&ktrace_mtx); if (p->p_ktrioparms != NULL && p->p_ktrioparms->vp == vp) - kiop = ktr_freeproc(p); + kiop1 = ktr_freeproc(p); + kiop = ktr_io_params_rele(kiop); mtx_unlock(&ktrace_mtx); PROC_UNLOCK(p); + ktr_io_params_free(kiop1); ktr_io_params_free(kiop); vrele(vp); }