Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys ktrace(9): Fix mutex detection in ktrcsw.
details: https://anonhg.NetBSD.org/src/rev/ec2c470c8452
branches: trunk
changeset: 368224:ec2c470c8452
user: riastradh <riastradh%NetBSD.org@localhost>
date: Wed Jun 29 22:10:43 2022 +0000
description:
ktrace(9): Fix mutex detection in ktrcsw.
On _entry_ to sleepq_block, l->l_syncobj is set so that ktrcsw
(ktr_csw) has the opportunity to detect whether it's a mutex or
rwlock. It is critical to avoid ktealloc when we're sleeping on a
mutex because we may be in softint context where ktealloc is
forbidden.
But after mi_switch, on _exit_ from sleepq_block, l->l_syncobj may
have been changed back to &sched_syncobj or something by
sleepq_remove, and so ktrcsw can no longer rely on l->l_syncobj to
determine whether we _were_ sleeping on a mutex or not.
Instead, save the syncobj in sleepq_block and pass it through as an
argument to ktrcsw.
Reported-by: syzbot+414edba9d161b7502658%syzkaller.appspotmail.com@localhost
Reported-by: syzbot+4425c97ac717b12495a2%syzkaller.appspotmail.com@localhost
Reported-by: syzbot+5812565b926ee8eb5cf3%syzkaller.appspotmail.com@localhost
Reported-by: syzbot+8b9d7b066c32dbcdc63b%syzkaller.appspotmail.com@localhost
Reported-by: syzbot+909a8e743c967d97f433%syzkaller.appspotmail.com@localhost
Reported-by: syzbot+e2a34bb5509bea0bba11%syzkaller.appspotmail.com@localhost
Reported-by: syzbot+faaea3aad6c9d0829f76%syzkaller.appspotmail.com@localhost
diffstat:
sys/kern/kern_ktrace.c | 15 ++++++++++-----
sys/kern/kern_sleepq.c | 9 +++++----
sys/sys/ktrace.h | 10 ++++++----
3 files changed, 21 insertions(+), 13 deletions(-)
diffs (130 lines):
diff -r 2ef096b490c9 -r ec2c470c8452 sys/kern/kern_ktrace.c
--- a/sys/kern/kern_ktrace.c Wed Jun 29 19:43:46 2022 +0000
+++ b/sys/kern/kern_ktrace.c Wed Jun 29 22:10:43 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_ktrace.c,v 1.180 2022/06/27 03:56:37 riastradh Exp $ */
+/* $NetBSD: kern_ktrace.c,v 1.181 2022/06/29 22:10:43 riastradh Exp $ */
/*-
* Copyright (c) 2006, 2007, 2008, 2020 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_ktrace.c,v 1.180 2022/06/27 03:56:37 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_ktrace.c,v 1.181 2022/06/29 22:10:43 riastradh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -76,6 +76,7 @@
#include <sys/ioctl.h>
#include <sys/callout.h>
#include <sys/kauth.h>
+#include <sys/cpu.h>
#include <sys/mount.h>
#include <sys/syscallargs.h>
@@ -807,7 +808,7 @@
}
void
-ktr_csw(int out, int user)
+ktr_csw(int out, int user, const struct syncobj *syncobj)
{
lwp_t *l = curlwp;
struct proc *p = l->l_proc;
@@ -819,10 +820,14 @@
/*
* Don't record context switches resulting from blocking on
- * locks; it's too easy to get duff results.
+ * locks; the results are not useful, and the mutex may be in a
+ * softint, which would lead us to ktealloc in softint context,
+ * which is forbidden.
*/
- if (l->l_syncobj == &mutex_syncobj || l->l_syncobj == &rw_syncobj)
+ if (syncobj == &mutex_syncobj || syncobj == &rw_syncobj)
return;
+ KASSERT(!cpu_intr_p());
+ KASSERT(!cpu_softintr_p());
/*
* We can't sleep if we're already going to sleep (if original
diff -r 2ef096b490c9 -r ec2c470c8452 sys/kern/kern_sleepq.c
--- a/sys/kern/kern_sleepq.c Wed Jun 29 19:43:46 2022 +0000
+++ b/sys/kern/kern_sleepq.c Wed Jun 29 22:10:43 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_sleepq.c,v 1.71 2022/04/08 10:17:55 andvar Exp $ */
+/* $NetBSD: kern_sleepq.c,v 1.72 2022/06/29 22:10:43 riastradh Exp $ */
/*-
* Copyright (c) 2006, 2007, 2008, 2009, 2019, 2020 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_sleepq.c,v 1.71 2022/04/08 10:17:55 andvar Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sleepq.c,v 1.72 2022/06/29 22:10:43 riastradh Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -309,8 +309,9 @@
lwp_t *l = curlwp;
bool early = false;
int biglocks = l->l_biglocks;
+ struct syncobj *syncobj = l->l_syncobj;
- ktrcsw(1, 0);
+ ktrcsw(1, 0, syncobj);
/*
* If sleeping interruptably, check for pending signals, exits or
@@ -397,7 +398,7 @@
}
}
- ktrcsw(0, 0);
+ ktrcsw(0, 0, syncobj);
if (__predict_false(biglocks != 0)) {
KERNEL_LOCK(biglocks, NULL);
}
diff -r 2ef096b490c9 -r ec2c470c8452 sys/sys/ktrace.h
--- a/sys/sys/ktrace.h Wed Jun 29 19:43:46 2022 +0000
+++ b/sys/sys/ktrace.h Wed Jun 29 22:10:43 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ktrace.h,v 1.67 2021/09/14 22:01:40 christos Exp $ */
+/* $NetBSD: ktrace.h,v 1.68 2022/06/29 22:10:43 riastradh Exp $ */
/*
* Copyright (c) 1988, 1993
@@ -297,6 +297,8 @@
#else
+struct syncobj;
+
void ktrinit(void);
void ktrderef(struct proc *);
void ktradref(struct proc *);
@@ -307,7 +309,7 @@
int ktruser(const char *, void *, size_t, int);
bool ktr_point(int);
-void ktr_csw(int, int);
+void ktr_csw(int, int, const struct syncobj *);
void ktr_emul(void);
void ktr_geniov(int, enum uio_rw, struct iovec *, size_t, int);
void ktr_genio(int, enum uio_rw, const void *, size_t, int);
@@ -349,10 +351,10 @@
}
static __inline void
-ktrcsw(int a, int b)
+ktrcsw(int a, int b, const struct syncobj *c)
{
if (__predict_false(ktrace_on))
- ktr_csw(a, b);
+ ktr_csw(a, b, c);
}
static __inline void
Home |
Main Index |
Thread Index |
Old Index