git: e4b16f2fb18b - main - ktrace: Avoid recursion in namei()

Mark Johnston markj at FreeBSD.org
Sat May 22 16:17:50 UTC 2021


The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=e4b16f2fb18bcb6ed2592a7b6983d5df04813a70

commit e4b16f2fb18bcb6ed2592a7b6983d5df04813a70
Author:     Mark Johnston <markj at FreeBSD.org>
AuthorDate: 2021-05-22 16:07:32 +0000
Commit:     Mark Johnston <markj at FreeBSD.org>
CommitDate: 2021-05-22 16:07:32 +0000

    ktrace: Avoid recursion in namei()
    
    sys_ktrace() calls namei(), which may call ktrnamei().  But sys_ktrace()
    also calls ktrace_enter() first, so if the caller is itself being
    traced, the assertion in ktrace_enter() is triggered.  And, ktrnamei()
    does not check for recursion like most other ktrace ops do.
    
    Fix the bug by simply deferring the ktrace_enter() call.
    
    Also make the parameter to ktrnamei() const and convert to ANSI.
    
    Reported by:    syzbot+d0a4de45e58d3c08af4b at syzkaller.appspotmail.com
    Reviewed by:    kib
    MFC after:      1 week
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D30340
---
 sys/kern/kern_ktrace.c | 13 +++++--------
 sys/sys/ktrace.h       |  2 +-
 2 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index 8783600df6b1..875c079df3b9 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -698,8 +698,7 @@ ktruserret(struct thread *td)
 }
 
 void
-ktrnamei(path)
-	char *path;
+ktrnamei(const char *path)
 {
 	struct ktr_request *req;
 	int namelen;
@@ -1017,7 +1016,6 @@ sys_ktrace(struct thread *td, struct ktrace_args *uap)
 		return (EINVAL);
 
 	kiop = NULL;
-	ktrace_enter(td);
 	if (ops != KTROP_CLEAR) {
 		/*
 		 * an operation which requires a file argument.
@@ -1025,23 +1023,22 @@ sys_ktrace(struct thread *td, struct ktrace_args *uap)
 		NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->fname, td);
 		flags = FREAD | FWRITE | O_NOFOLLOW;
 		error = vn_open(&nd, &flags, 0, NULL);
-		if (error) {
-			ktrace_exit(td);
+		if (error)
 			return (error);
-		}
 		NDFREE(&nd, NDF_ONLY_PNBUF);
 		vp = nd.ni_vp;
 		VOP_UNLOCK(vp);
 		if (vp->v_type != VREG) {
-			(void) vn_close(vp, FREAD|FWRITE, td->td_ucred, td);
-			ktrace_exit(td);
+			(void)vn_close(vp, FREAD|FWRITE, td->td_ucred, td);
 			return (EACCES);
 		}
 		kiop = ktr_io_params_alloc(td, vp);
 	}
+
 	/*
 	 * Clear all uses of the tracefile.
 	 */
+	ktrace_enter(td);
 	if (ops == KTROP_CLEARFILE) {
 restart:
 		sx_slock(&allproc_lock);
diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h
index 50030d002f97..f1f9361f9f82 100644
--- a/sys/sys/ktrace.h
+++ b/sys/sys/ktrace.h
@@ -269,7 +269,7 @@ struct ktr_io_params;
 
 struct vnode *ktr_get_tracevp(struct proc *, bool);
 void	ktr_io_params_free(struct ktr_io_params *);
-void	ktrnamei(char *);
+void	ktrnamei(const char *);
 void	ktrcsw(int, int, const char *);
 void	ktrpsig(int, sig_t, sigset_t *, int);
 void	ktrfault(vm_offset_t, int);


More information about the dev-commits-src-all mailing list