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-main
mailing list