Date: Sun, 12 Mar 2017 13:48:24 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r315155 - in head/sys: kern sys Message-ID: <201703121348.v2CDmOpp070774@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Sun Mar 12 13:48:24 2017 New Revision: 315155 URL: https://svnweb.freebsd.org/changeset/base/315155 Log: Ktracing kevent(2) calls with unusual arguments might leads to an overly large allocation requests. When ktrace-ing io, sys_kevent() allocates memory to copy the requested changes and reported events. Allocations are sized by the incoming syscall lengths arguments, which are user-controlled, and might cause overflow in calculations or too large allocations. Since io trace chunks are limited by ktr_geniosize, there is no sense it even trying to satisfy unbounded allocations. Export ktr_geniosize and clamp the buffers sizes in advance. PR: 217435 Reported by: Tim Newsham <tim.newsham@nccgroup.trust> Sponsored by: The FreeBSD Foundation MFC after: 1 week Modified: head/sys/kern/kern_event.c head/sys/kern/kern_ktrace.c head/sys/sys/ktrace.h Modified: head/sys/kern/kern_event.c ============================================================================== --- head/sys/kern/kern_event.c Sun Mar 12 13:42:40 2017 (r315154) +++ head/sys/kern/kern_event.c Sun Mar 12 13:48:24 2017 (r315155) @@ -887,6 +887,15 @@ kern_kqueue(struct thread *td, int flags return (0); } +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)); +} + #ifndef _SYS_SYSPROTO_H_ struct kevent_args { int fd; @@ -910,6 +919,7 @@ sys_kevent(struct thread *td, struct kev struct iovec ktriov; struct uio *ktruioin = NULL; struct uio *ktruioout = NULL; + u_int kgio; #endif if (uap->timeout != NULL) { @@ -922,13 +932,15 @@ sys_kevent(struct thread *td, struct kev #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); } @@ -939,9 +951,9 @@ sys_kevent(struct thread *td, struct kev #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 Modified: head/sys/kern/kern_ktrace.c ============================================================================== --- head/sys/kern/kern_ktrace.c Sun Mar 12 13:42:40 2017 (r315154) +++ head/sys/kern/kern_ktrace.c Sun Mar 12 13:48:24 2017 (r315155) @@ -132,7 +132,7 @@ static SYSCTL_NODE(_kern, OID_AUTO, ktra 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"); Modified: head/sys/sys/ktrace.h ============================================================================== --- head/sys/sys/ktrace.h Sun Mar 12 13:42:40 2017 (r315154) +++ head/sys/sys/ktrace.h Sun Mar 12 13:48:24 2017 (r315155) @@ -276,7 +276,7 @@ void ktrcapfail(enum ktr_cap_fail_type, 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>
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201703121348.v2CDmOpp070774>