summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2017-03-18 03:49:50 +0000
committerkib <kib@FreeBSD.org>2017-03-18 03:49:50 +0000
commit68c2de3a169fde018136098363728f160fef3ede (patch)
treeac1853152f1dd460104f7d82ad388b1f45af4f6a
parent7169011bf02f04f1750bf7163e144b30eae0c21c (diff)
downloadFreeBSD-src-68c2de3a169fde018136098363728f160fef3ede.zip
FreeBSD-src-68c2de3a169fde018136098363728f160fef3ede.tar.gz
MFC r315155:
Ktracing kevent(2) calls with unusual arguments might leads to an overly large allocation requests. PR: 217435 MFC r315237: Hide kev_iovlen() definition under #ifdef KTRACE.
-rw-r--r--sys/kern/kern_event.c20
-rw-r--r--sys/kern/kern_ktrace.c2
-rw-r--r--sys/sys/ktrace.h2
3 files changed, 19 insertions, 5 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 0e1f7f1..d9a2a8a 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -859,6 +859,17 @@ kern_kqueue(struct thread *td, int flags, struct filecaps *fcaps)
return (0);
}
+#ifdef KTRACE
+static size_t
+kev_iovlen(int n, u_int kgio)
+{
+
+ if (n < 0 || n >= kgio / sizeof(struct kevent))
+ return (kgio);
+ return (n * sizeof(struct kevent));
+}
+#endif
+
#ifndef _SYS_SYSPROTO_H_
struct kevent_args {
int fd;
@@ -882,6 +893,7 @@ sys_kevent(struct thread *td, struct kevent_args *uap)
struct iovec ktriov;
struct uio *ktruioin = NULL;
struct uio *ktruioout = NULL;
+ u_int kgio;
#endif
if (uap->timeout != NULL) {
@@ -894,13 +906,15 @@ sys_kevent(struct thread *td, struct kevent_args *uap)
#ifdef KTRACE
if (KTRPOINT(td, KTR_GENIO)) {
+ kgio = ktr_geniosize;
ktriov.iov_base = uap->changelist;
- ktriov.iov_len = uap->nchanges * sizeof(struct kevent);
+ ktriov.iov_len = kev_iovlen(uap->nchanges, kgio);
ktruio = (struct uio){ .uio_iov = &ktriov, .uio_iovcnt = 1,
.uio_segflg = UIO_USERSPACE, .uio_rw = UIO_READ,
.uio_td = td };
ktruioin = cloneuio(&ktruio);
ktriov.iov_base = uap->eventlist;
+ ktriov.iov_len = kev_iovlen(uap->nevents, kgio);
ktriov.iov_len = uap->nevents * sizeof(struct kevent);
ktruioout = cloneuio(&ktruio);
}
@@ -911,9 +925,9 @@ sys_kevent(struct thread *td, struct kevent_args *uap)
#ifdef KTRACE
if (ktruioin != NULL) {
- ktruioin->uio_resid = uap->nchanges * sizeof(struct kevent);
+ ktruioin->uio_resid = kev_iovlen(uap->nchanges, kgio);
ktrgenio(uap->fd, UIO_WRITE, ktruioin, 0);
- ktruioout->uio_resid = td->td_retval[0] * sizeof(struct kevent);
+ ktruioout->uio_resid = kev_iovlen(td->td_retval[0], kgio);
ktrgenio(uap->fd, UIO_READ, ktruioout, error);
}
#endif
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index 676cd43..113e386 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -132,7 +132,7 @@ static SYSCTL_NODE(_kern, OID_AUTO, ktrace, CTLFLAG_RD, 0, "KTRACE options");
static u_int ktr_requestpool = KTRACE_REQUEST_POOL;
TUNABLE_INT("kern.ktrace.request_pool", &ktr_requestpool);
-static u_int ktr_geniosize = PAGE_SIZE;
+u_int ktr_geniosize = PAGE_SIZE;
SYSCTL_UINT(_kern_ktrace, OID_AUTO, genio_size, CTLFLAG_RWTUN, &ktr_geniosize,
0, "Maximum size of genio event payload");
diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h
index e63a41a..9b5824b 100644
--- a/sys/sys/ktrace.h
+++ b/sys/sys/ktrace.h
@@ -276,7 +276,7 @@ void ktrcapfail(enum ktr_cap_fail_type, const cap_rights_t *,
ktrstruct("sockaddr", (s), ((struct sockaddr *)(s))->sa_len)
#define ktrstat(s) \
ktrstruct("stat", (s), sizeof(struct stat))
-
+extern u_int ktr_geniosize;
#else
#include <sys/cdefs.h>
OpenPOWER on IntegriCloud