diff options
author | kib <kib@FreeBSD.org> | 2017-03-18 03:49:50 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2017-03-18 03:49:50 +0000 |
commit | 68c2de3a169fde018136098363728f160fef3ede (patch) | |
tree | ac1853152f1dd460104f7d82ad388b1f45af4f6a | |
parent | 7169011bf02f04f1750bf7163e144b30eae0c21c (diff) | |
download | FreeBSD-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.c | 20 | ||||
-rw-r--r-- | sys/kern/kern_ktrace.c | 2 | ||||
-rw-r--r-- | sys/sys/ktrace.h | 2 |
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> |