diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index e6d3b87ed82a..af011c31bca3 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -1321,12 +1321,15 @@ static void ktrwrite(struct ktr_desc *ktd, struct ktrace_entry *kte) { size_t hlen; - struct uio auio; + struct uio auio, oauio; struct iovec aiov[64], *iov; struct ktrace_entry *top = kte; struct ktr_header *kth; file_t *fp = ktd->ktd_fp; int error; + + memset(&auio, 0, sizeof(auio)); + memset(aiov, 0, sizeof(aiov)); next: auio.uio_iov = iov = &aiov[0]; auio.uio_offset = 0; @@ -1361,11 +1364,15 @@ next: MAX(sizeof(kth->_v._v0), sizeof(kth->_v._v1)); break; } + KASSERT(auio.uio_iovcnt < __arraycount(aiov)); + KASSERT(iov < aiov + __arraycount(aiov)); iov->iov_base = (void *)kth; iov++->iov_len = hlen; auio.uio_resid += hlen; auio.uio_iovcnt++; if (kth->ktr_len > 0) { + KASSERT(auio.uio_iovcnt < __arraycount(aiov)); + KASSERT(iov < aiov + __arraycount(aiov)); iov->iov_base = kte->kte_buf; iov++->iov_len = kth->ktr_len; auio.uio_resid += kth->ktr_len; @@ -1375,8 +1382,37 @@ next: auio.uio_iovcnt < sizeof(aiov) / sizeof(aiov[0]) - 1); again: + KASSERTMSG(auio.uio_iovcnt >= 0, "iovcnt=%d", auio.uio_iovcnt); + KASSERTMSG(auio.uio_iovcnt <= __arraycount(aiov), "iovcnt=%d max=%zu", + auio.uio_iovcnt, __arraycount(aiov)); + oauio = auio; error = (*fp->f_ops->fo_write)(fp, &fp->f_offset, &auio, fp->f_cred, FOF_UPDATE_OFFSET); + KASSERTMSG(auio.uio_iovcnt >= 0, "iovcnt=%d", auio.uio_iovcnt); + KASSERTMSG(auio.uio_iovcnt <= __arraycount(aiov), "iovcnt=%d max=%zu", + auio.uio_iovcnt, __arraycount(aiov)); + KASSERTMSG(oauio.uio_resid >= auio.uio_resid, + "before=%zu after=%zu error=%d", + oauio.uio_resid, auio.uio_resid, error); + KASSERTMSG(oauio.uio_iov <= auio.uio_iov, + "before=%p after=%p error=%d", + oauio.uio_iov, auio.uio_iov, error); + KASSERTMSG(oauio.uio_iovcnt >= auio.uio_iovcnt, + "before=%d after=%d error=%d", + oauio.uio_iovcnt, auio.uio_iovcnt, error); + KASSERTMSG(aiov <= auio.uio_iov, + "auio.iov=%p &aiov[0]=%p error=%d", + auio.uio_iov, aiov, error); + KASSERTMSG(auio.uio_iov <= aiov + __arraycount(aiov), + "auio.uio_iov=%p &aiov[%zu]=%p error=%d", + auio.uio_iov, __arraycount(aiov), aiov + __arraycount(aiov), + error); + KASSERTMSG((auio.uio_iovcnt <= + __arraycount(aiov) - (auio.uio_iov - aiov)), + "auio.uio_iovcnt=%d auio.uio_iov=%p aiov=%p __arraycount(aiov)=%zu" + " error=%d", + auio.uio_iovcnt, auio.uio_iov, aiov, __arraycount(aiov), error); + switch (error) { case 0: diff --git a/sys/kern/subr_copy.c b/sys/kern/subr_copy.c index e62b219d522b..cf5768c29f64 100644 --- a/sys/kern/subr_copy.c +++ b/sys/kern/subr_copy.c @@ -112,10 +112,11 @@ uiomove(void *buf, size_t n, struct uio *uio) KASSERT(uio->uio_rw == UIO_READ || uio->uio_rw == UIO_WRITE); while (n > 0 && uio->uio_resid) { + KASSERT(uio->uio_iovcnt > 0); iov = uio->uio_iov; cnt = iov->iov_len; if (cnt == 0) { - KASSERT(uio->uio_iovcnt > 0); + KASSERT(uio->uio_iovcnt > 1); uio->uio_iov++; uio->uio_iovcnt--; continue; diff --git a/sys/kern/tty.c b/sys/kern/tty.c index fe2a3b05efb3..d02691b10035 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -2278,6 +2278,7 @@ ttwrite(struct tty *tp, struct uio *uio, int flag) * offset and iov pointers have moved forward, but it doesn't matter * (the call will either return short or restart with a new uio). */ + KASSERTMSG(error || cc == 0, "error=%d cc=%d", error, cc); uio->uio_resid += cc; return (error);