diff options
author | green <green@FreeBSD.org> | 2000-07-02 08:08:09 +0000 |
---|---|---|
committer | green <green@FreeBSD.org> | 2000-07-02 08:08:09 +0000 |
commit | 9707bc34b009d1e09d192ec84d1ddc8e8693006f (patch) | |
tree | 176c788b7d732a310aa42a0b4652b645bc735a99 /sys/kern/sys_generic.c | |
parent | c350a86095dd249ad9e0371c7caaf6a5c52a0260 (diff) | |
download | FreeBSD-src-9707bc34b009d1e09d192ec84d1ddc8e8693006f.zip FreeBSD-src-9707bc34b009d1e09d192ec84d1ddc8e8693006f.tar.gz |
Modify ktrace's general I/O tracing, ktrgenio(), to use a struct uio *
instead of a struct iovec * array and int len. Get rid of stupidly trying
to allocate all of the memory and copyin()ing the entire iovec[], and
instead just do the proper VOP_WRITE() in ktrwrite() using a copy of
the struct uio that the syscall originally used.
This solves the DoS which could easily be performed; to work around the
DoS, one could also remove "options KTRACE" from the kernel. This is
a very strong MFC candidate for 4.1.
Found by: art@OpenBSD.org
Diffstat (limited to 'sys/kern/sys_generic.c')
-rw-r--r-- | sys/kern/sys_generic.c | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index bf33a4d..562536a 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -154,6 +154,7 @@ dofileread(p, fp, fd, buf, nbyte, offset, flags) long cnt, error = 0; #ifdef KTRACE struct iovec ktriov; + struct uio ktruio; #endif aiov.iov_base = (caddr_t)buf; @@ -171,8 +172,10 @@ dofileread(p, fp, fd, buf, nbyte, offset, flags) /* * if tracing, save a copy of iovec */ - if (KTRPOINT(p, KTR_GENIO)) + if (KTRPOINT(p, KTR_GENIO)) { ktriov = aiov; + ktruio = auio; + } #endif cnt = nbyte; if ((error = fo_read(fp, &auio, fp->f_cred, flags, p))) @@ -181,8 +184,11 @@ dofileread(p, fp, fd, buf, nbyte, offset, flags) error = 0; cnt -= auio.uio_resid; #ifdef KTRACE - if (KTRPOINT(p, KTR_GENIO) && error == 0) - ktrgenio(p->p_tracep, fd, UIO_READ, &ktriov, cnt, error); + if (error == 0 && KTRPOINT(p, KTR_GENIO)) { + ktruio.uio_iov = &ktriov; + ktruio.uio_resid = cnt; + ktrgenio(p->p_tracep, fd, UIO_READ, &ktruio, error); + } #endif p->p_retval[0] = cnt; return (error); @@ -213,6 +219,7 @@ readv(p, uap) u_int iovlen; #ifdef KTRACE struct iovec *ktriov = NULL; + struct uio ktruio; #endif if ((fp = getfp(fdp, uap->fd, FREAD)) == NULL) @@ -252,6 +259,7 @@ readv(p, uap) if (KTRPOINT(p, KTR_GENIO)) { MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); + ktruio = auio; } #endif cnt = auio.uio_resid; @@ -262,9 +270,12 @@ readv(p, uap) cnt -= auio.uio_resid; #ifdef KTRACE if (ktriov != NULL) { - if (error == 0) - ktrgenio(p->p_tracep, uap->fd, UIO_READ, ktriov, - cnt, error); + if (error == 0) { + ktruio.uio_iov = ktriov; + ktruio.uio_resid = cnt; + ktrgenio(p->p_tracep, uap->fd, UIO_READ, &ktruio, + error); + } FREE(ktriov, M_TEMP); } #endif @@ -338,6 +349,7 @@ dofilewrite(p, fp, fd, buf, nbyte, offset, flags) long cnt, error = 0; #ifdef KTRACE struct iovec ktriov; + struct uio ktruio; #endif aiov.iov_base = (void *)buf; @@ -353,10 +365,12 @@ dofilewrite(p, fp, fd, buf, nbyte, offset, flags) auio.uio_procp = p; #ifdef KTRACE /* - * if tracing, save a copy of iovec + * if tracing, save a copy of iovec and uio */ - if (KTRPOINT(p, KTR_GENIO)) + if (KTRPOINT(p, KTR_GENIO)) { ktriov = aiov; + ktruio = auio; + } #endif cnt = nbyte; if ((error = fo_write(fp, &auio, fp->f_cred, flags, p))) { @@ -368,9 +382,11 @@ dofilewrite(p, fp, fd, buf, nbyte, offset, flags) } cnt -= auio.uio_resid; #ifdef KTRACE - if (KTRPOINT(p, KTR_GENIO) && error == 0) - ktrgenio(p->p_tracep, fd, UIO_WRITE, - &ktriov, cnt, error); + if (error == 0 && KTRPOINT(p, KTR_GENIO)) { + ktruio.uio_iov = &ktriov; + ktruio.uio_resid = cnt; + ktrgenio(p->p_tracep, fd, UIO_WRITE, &ktruio, error); + } #endif p->p_retval[0] = cnt; return (error); @@ -401,6 +417,7 @@ writev(p, uap) u_int iovlen; #ifdef KTRACE struct iovec *ktriov = NULL; + struct uio ktruio; #endif if ((fp = getfp(fdp, uap->fd, FWRITE)) == NULL) @@ -439,11 +456,12 @@ writev(p, uap) } #ifdef KTRACE /* - * if tracing, save a copy of iovec + * if tracing, save a copy of iovec and uio */ if (KTRPOINT(p, KTR_GENIO)) { MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); + ktruio = auio; } #endif cnt = auio.uio_resid; @@ -457,9 +475,12 @@ writev(p, uap) cnt -= auio.uio_resid; #ifdef KTRACE if (ktriov != NULL) { - if (error == 0) - ktrgenio(p->p_tracep, uap->fd, UIO_WRITE, - ktriov, cnt, error); + if (error == 0) { + ktruio.uio_iov = ktriov; + ktruio.uio_resid = cnt; + ktrgenio(p->p_tracep, uap->fd, UIO_WRITE, &ktruio, + error); + } FREE(ktriov, M_TEMP); } #endif |