git: fc369a353b5b - main - ktrace: fix a race between writes and close
Konstantin Belousov
kib at FreeBSD.org
Sat May 22 20:14:23 UTC 2021
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=fc369a353b5b5e0f8046687fcbd78a7cd9ad1810
commit fc369a353b5b5e0f8046687fcbd78a7cd9ad1810
Author: Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2021-05-22 12:40:00 +0000
Commit: Konstantin Belousov <kib at FreeBSD.org>
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);
}
More information about the dev-commits-src-main
mailing list