diff options
author | csjp <csjp@FreeBSD.org> | 2005-08-08 18:54:35 +0000 |
---|---|---|
committer | csjp <csjp@FreeBSD.org> | 2005-08-08 18:54:35 +0000 |
commit | b42a694c8b2ad94f516017e13ec5e022747c40ba (patch) | |
tree | e24e3e4af6f172116d59211a4ae40974433ed719 | |
parent | 3215a6e2e355a587ea6894414dc9be4c5be53ed7 (diff) | |
download | FreeBSD-src-b42a694c8b2ad94f516017e13ec5e022747c40ba.zip FreeBSD-src-b42a694c8b2ad94f516017e13ec5e022747c40ba.tar.gz |
Check to see if we wired the user-supplied buffers in SYSCTL_OUT, if
the buffer has not been wired and we are holding any non-sleep-able locks,
drop a witness warning. If the buffer has not been wired, it is possible
that the writing of the data can sleep, especially if the page is not in
memory. This can result in a number of different locking issues, including
dead locks.
MFC after: 1 week
Discussed with: rwatson
Reviewed by: jhb
-rw-r--r-- | sys/kern/kern_sysctl.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 522a55f..31482f8 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1066,7 +1066,12 @@ sysctl_old_user(struct sysctl_req *req, const void *p, size_t l) req->oldidx += l; if (req->oldptr == NULL) return (0); - if (req->lock == REQ_LOCKED) + /* + * If we have not wired the user supplied buffer and we are currently + * holding locks, drop a witness warning, as it's possible that + * write operations to the user page can sleep. + */ + if (req->lock != REQ_WIRED) WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "sysctl_old_user()"); i = l; |