From: Matthew Dillon Date: Fri, 12 Jan 2007 06:06:58 +0000 (+0000) Subject: Fix a number of places where the kernel assumed it could directly access X-Git-Tag: v2.0.1~3739 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/e7440b28c467b60ff768535f0fd40344e003808e Fix a number of places where the kernel assumed it could directly access user memory. Primarily the core dump code. --- diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index dfb648524e..ad731a1390 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -27,7 +27,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/kern/imgact_elf.c,v 1.73.2.13 2002/12/28 19:49:41 dillon Exp $ - * $DragonFly: src/sys/kern/imgact_elf.c,v 1.46 2006/12/28 21:24:01 dillon Exp $ + * $DragonFly: src/sys/kern/imgact_elf.c,v 1.47 2007/01/12 06:06:57 dillon Exp $ */ #include @@ -994,7 +994,7 @@ generic_elf_coredump(struct proc *p, struct file *fp, off_t limit) php = (Elf_Phdr *)(target.buf + sizeof(Elf_Ehdr)) + 1; for (i = 0; i < seginfo.count; i++) { error = fp_write(fp, (caddr_t)php->p_vaddr, - php->p_filesz, &nbytes); + php->p_filesz, &nbytes, UIO_USERSPACE); if (error != 0) break; php++; @@ -1266,8 +1266,10 @@ elf_corehdr(struct proc *p, struct file *fp, struct ucred *cred, int numsegs, kfree(tempdata, M_TEMP); /* Write it to the core file. */ - if (error == 0) - error = fp_write(fp, target->buf, target->off, &nbytes); + if (error == 0) { + error = fp_write(fp, target->buf, target->off, &nbytes, + UIO_SYSSPACE); + } return error; } diff --git a/sys/kern/kern_checkpoint.c b/sys/kern/kern_checkpoint.c index 3f2fd86caa..e0cd23ebb2 100644 --- a/sys/kern/kern_checkpoint.c +++ b/sys/kern/kern_checkpoint.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/kern_checkpoint.c,v 1.14 2006/12/23 00:35:03 swildner Exp $ + * $DragonFly: src/sys/kern/kern_checkpoint.c,v 1.15 2007/01/12 06:06:57 dillon Exp $ */ #include @@ -99,7 +99,7 @@ read_check(struct file *fp, void *buf, size_t nbyte) int error; PRINTF(("reading %d bytes\n", nbyte)); - error = fp_read(fp, buf, nbyte, &nread, 1); + error = fp_read(fp, buf, nbyte, &nread, 1, UIO_SYSSPACE); if (error) { PRINTF(("read failed - %d", error)); } else if (nread != nbyte) { diff --git a/sys/kern/kern_firmware.c b/sys/kern/kern_firmware.c index efabfd4b26..d57a29541b 100644 --- a/sys/kern/kern_firmware.c +++ b/sys/kern/kern_firmware.c @@ -30,7 +30,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/kern_firmware.c,v 1.7 2006/12/23 00:35:04 swildner Exp $ + * $DragonFly: src/sys/kern/kern_firmware.c,v 1.8 2007/01/12 06:06:57 dillon Exp $ */ #include @@ -177,7 +177,8 @@ firmware_image_load_file(const char *image_name) if (img == NULL) goto fail_stat; - error = fp_read(fp, img->fw_image, img->fw_imglen, &nread, 1); + error = fp_read(fp, img->fw_image, img->fw_imglen, &nread, + 1, UIO_SYSSPACE); if (error != 0 || nread != img->fw_imglen) { kprintf("firmware image could not be read: %d\n", error); goto fail_read; diff --git a/sys/kern/kern_fp.c b/sys/kern/kern_fp.c index 9d7f51ddc9..980b6e9cc3 100644 --- a/sys/kern/kern_fp.c +++ b/sys/kern/kern_fp.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/kern_fp.c,v 1.19 2006/11/07 17:51:23 dillon Exp $ + * $DragonFly: src/sys/kern/kern_fp.c,v 1.20 2007/01/12 06:06:57 dillon Exp $ */ /* @@ -204,7 +204,8 @@ bad2: * transfer will be used. */ int -fp_pread(file_t fp, void *buf, size_t nbytes, off_t offset, ssize_t *res) +fp_pread(file_t fp, void *buf, size_t nbytes, off_t offset, ssize_t *res, + enum uio_seg seg) { struct uio auio; struct iovec aiov; @@ -223,10 +224,7 @@ fp_pread(file_t fp, void *buf, size_t nbytes, off_t offset, ssize_t *res) auio.uio_offset = offset; auio.uio_resid = nbytes; auio.uio_rw = UIO_READ; - if ((vm_offset_t)buf < VM_MAX_USER_ADDRESS) - auio.uio_segflg = UIO_USERSPACE; - else - auio.uio_segflg = UIO_SYSSPACE; + auio.uio_segflg = seg; auio.uio_td = curthread; count = nbytes; @@ -245,7 +243,8 @@ fp_pread(file_t fp, void *buf, size_t nbytes, off_t offset, ssize_t *res) } int -fp_read(file_t fp, void *buf, size_t nbytes, ssize_t *res, int all) +fp_read(file_t fp, void *buf, size_t nbytes, ssize_t *res, int all, + enum uio_seg seg) { struct uio auio; struct iovec aiov; @@ -264,10 +263,7 @@ fp_read(file_t fp, void *buf, size_t nbytes, ssize_t *res, int all) auio.uio_offset = 0; auio.uio_resid = nbytes; auio.uio_rw = UIO_READ; - if ((vm_offset_t)buf < VM_MAX_USER_ADDRESS) - auio.uio_segflg = UIO_USERSPACE; - else - auio.uio_segflg = UIO_SYSSPACE; + auio.uio_segflg = seg; auio.uio_td = curthread; /* @@ -305,7 +301,8 @@ fp_read(file_t fp, void *buf, size_t nbytes, ssize_t *res, int all) } int -fp_pwrite(file_t fp, void *buf, size_t nbytes, off_t offset, ssize_t *res) +fp_pwrite(file_t fp, void *buf, size_t nbytes, off_t offset, ssize_t *res, + enum uio_seg seg) { struct uio auio; struct iovec aiov; @@ -324,10 +321,7 @@ fp_pwrite(file_t fp, void *buf, size_t nbytes, off_t offset, ssize_t *res) auio.uio_offset = offset; auio.uio_resid = nbytes; auio.uio_rw = UIO_WRITE; - if ((vm_offset_t)buf < VM_MAX_USER_ADDRESS) - auio.uio_segflg = UIO_USERSPACE; - else - auio.uio_segflg = UIO_SYSSPACE; + auio.uio_segflg = seg; auio.uio_td = curthread; count = nbytes; @@ -347,7 +341,7 @@ fp_pwrite(file_t fp, void *buf, size_t nbytes, off_t offset, ssize_t *res) int -fp_write(file_t fp, void *buf, size_t nbytes, ssize_t *res) +fp_write(file_t fp, void *buf, size_t nbytes, ssize_t *res, enum uio_seg seg) { struct uio auio; struct iovec aiov; @@ -366,10 +360,7 @@ fp_write(file_t fp, void *buf, size_t nbytes, ssize_t *res) auio.uio_offset = 0; auio.uio_resid = nbytes; auio.uio_rw = UIO_WRITE; - if ((vm_offset_t)buf < VM_MAX_USER_ADDRESS) - auio.uio_segflg = UIO_USERSPACE; - else - auio.uio_segflg = UIO_SYSSPACE; + auio.uio_segflg = seg; auio.uio_td = curthread; count = nbytes; diff --git a/sys/kern/kern_syslink.c b/sys/kern/kern_syslink.c index 4f907a709d..b05501417c 100644 --- a/sys/kern/kern_syslink.c +++ b/sys/kern/kern_syslink.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/kern_syslink.c,v 1.4 2006/12/23 00:35:04 swildner Exp $ + * $DragonFly: src/sys/kern/kern_syslink.c,v 1.5 2007/01/12 06:06:57 dillon Exp $ */ /* * This module implements the syslink() system call and protocol which @@ -257,8 +257,8 @@ syslink_rthread(void *arg) if (count == 0) break; error = fp_read(sldata->xfp, - slbuf->buf + (slbuf->windex & slbuf->bufmask), count, - &count, 0); + slbuf->buf + (slbuf->windex & slbuf->bufmask), + count, &count, 0, UIO_SYSSPACE); if (error) break; if (count == 0) @@ -386,7 +386,8 @@ syslink_wthread(void *arg) * Write it out whether it is PAD or not. XXX re-PAD for output * here. */ - error = fp_write(sldata->xfp, head, aligned_reclen, &count); + error = fp_write(sldata->xfp, head, aligned_reclen, &count, + UIO_SYSSPACE); if (error) break; if (count != aligned_reclen) { diff --git a/sys/kern/vfs_journal.c b/sys/kern/vfs_journal.c index 697f35275f..bedfd5f289 100644 --- a/sys/kern/vfs_journal.c +++ b/sys/kern/vfs_journal.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/vfs_journal.c,v 1.30 2006/12/23 00:35:04 swildner Exp $ + * $DragonFly: src/sys/kern/vfs_journal.c,v 1.31 2007/01/12 06:06:57 dillon Exp $ */ /* * The journaling protocol is intended to evolve into a two-way stream @@ -255,7 +255,7 @@ journal_wthread(void *info) jo->fifo.rindex += bytes; error = fp_write(jo->fp, jo->fifo.membase + ((jo->fifo.rindex - bytes) & jo->fifo.mask), - bytes, &res); + bytes, &res, UIO_SYSSPACE); if (error) { kprintf("journal_thread(%s) write, error %d\n", jo->id, error); /* XXX */ @@ -316,7 +316,8 @@ journal_rthread(void *info) * stream. */ if (transid == 0) { - error = fp_read(jo->fp, &ack, sizeof(ack), &count, 1); + error = fp_read(jo->fp, &ack, sizeof(ack), &count, + 1, UIO_SYSSPACE); #if 0 kprintf("fp_read ack error %d count %d\n", error, count); #endif diff --git a/sys/sys/file.h b/sys/sys/file.h index 00d3f8c44c..646fcc232a 100644 --- a/sys/sys/file.h +++ b/sys/sys/file.h @@ -32,7 +32,7 @@ * * @(#)file.h 8.3 (Berkeley) 1/9/95 * $FreeBSD: src/sys/sys/file.h,v 1.22.2.7 2002/11/21 23:39:24 sam Exp $ - * $DragonFly: src/sys/sys/file.h,v 1.24 2006/10/27 04:56:33 dillon Exp $ + * $DragonFly: src/sys/sys/file.h,v 1.25 2007/01/12 06:06:58 dillon Exp $ */ #ifndef _SYS_FILE_H_ @@ -59,6 +59,9 @@ #ifndef _SYS_NAMECACHE_H_ #include #endif +#ifndef _SYS_UIO_H_ +#include +#endif struct stat; struct proc; @@ -140,10 +143,10 @@ extern void fhold(struct file *fp); extern int fdrop (struct file *fp); extern int fp_open(const char *path, int flags, int mode, struct file **fpp); extern int fp_vpopen(struct vnode *vp, int flags, struct file **fpp); -extern int fp_pread(struct file *fp, void *buf, size_t nbytes, off_t offset, ssize_t *res); -extern int fp_pwrite(struct file *fp, void *buf, size_t nbytes, off_t offset, ssize_t *res); -extern int fp_read(struct file *fp, void *buf, size_t nbytes, ssize_t *res, int all); -extern int fp_write(struct file *fp, void *buf, size_t nbytes, ssize_t *res); +extern int fp_pread(struct file *fp, void *buf, size_t nbytes, off_t offset, ssize_t *res, enum uio_seg); +extern int fp_pwrite(struct file *fp, void *buf, size_t nbytes, off_t offset, ssize_t *res, enum uio_seg); +extern int fp_read(struct file *fp, void *buf, size_t nbytes, ssize_t *res, int all, enum uio_seg); +extern int fp_write(struct file *fp, void *buf, size_t nbytes, ssize_t *res, enum uio_seg); extern int fp_stat(struct file *fp, struct stat *ub); extern int fp_mmap(void *addr, size_t size, int prot, int flags, struct file *fp, off_t pos, void **resp);