summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authordg <dg@FreeBSD.org>1998-10-13 08:24:45 +0000
committerdg <dg@FreeBSD.org>1998-10-13 08:24:45 +0000
commit3defb6d13f481d8c8bb2d9014db42c8a5ee19f9d (patch)
tree64822d97637c55a2d7aeb4a999c847a5869bac46 /sys/kern
parent3280e5edc1739224a3e662ea57aa1746d1eb9105 (diff)
downloadFreeBSD-src-3defb6d13f481d8c8bb2d9014db42c8a5ee19f9d.zip
FreeBSD-src-3defb6d13f481d8c8bb2d9014db42c8a5ee19f9d.tar.gz
Fixed two potentially serious classes of bugs:
1) The vnode pager wasn't properly tracking the file size due to "size" being page rounded in some cases and not in others. This sometimes resulted in corrupted files. First noticed by Terry Lambert. Fixed by changing the "size" pager_alloc parameter to be a 64bit byte value (as opposed to a 32bit page index) and changing the pagers and their callers to deal with this properly. 2) Fixed a bogus type cast in round_page() and trunc_page() that caused some 64bit offsets and sizes to be scrambled. Removing the cast required adding casts at a few dozen callers. There may be problems with other bogus casts in close-by macros. A quick check seemed to indicate that those were okay, however.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/imgact_elf.c8
-rw-r--r--sys/kern/sys_pipe.c6
-rw-r--r--sys/kern/sysv_shm.c7
-rw-r--r--sys/kern/vfs_bio.c18
-rw-r--r--sys/kern/vfs_export.c7
-rw-r--r--sys/kern/vfs_subr.c7
6 files changed, 25 insertions, 28 deletions
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 2ffeb08..f3e787f 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -26,7 +26,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: imgact_elf.c,v 1.36 1998/10/03 04:12:09 jdp Exp $
+ * $Id: imgact_elf.c,v 1.37 1998/10/11 19:22:07 jdp Exp $
*/
#include "opt_rlimit.h"
@@ -193,7 +193,7 @@ elf_load_section(struct vmspace *vmspace, struct vnode *vp, vm_offset_t offset,
unsigned char *data_buf = 0;
size_t copy_len;
- map_addr = trunc_page(vmaddr);
+ map_addr = trunc_page((vm_offset_t)vmaddr);
if (memsz > filsz)
map_len = trunc_page(offset+filsz) - trunc_page(offset);
@@ -219,8 +219,8 @@ elf_load_section(struct vmspace *vmspace, struct vnode *vp, vm_offset_t offset,
* bit into it. The remaining space should be .bss...
*/
copy_len = (offset + filsz) - trunc_page(offset + filsz);
- map_addr = trunc_page(vmaddr + filsz);
- map_len = round_page(vmaddr + memsz) - map_addr;
+ map_addr = trunc_page((vm_offset_t)vmaddr + filsz);
+ map_len = round_page((vm_offset_t)vmaddr + memsz) - map_addr;
if (map_len != 0) {
if (error = vm_map_find(&vmspace->vm_map, NULL, 0,
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index 2c8f9ae..9b60e26 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -16,7 +16,7 @@
* 4. Modifications may be freely made to this file if the above conditions
* are met.
*
- * $Id: sys_pipe.c,v 1.41 1998/03/28 10:33:07 bde Exp $
+ * $Id: sys_pipe.c,v 1.42 1998/06/07 17:11:39 dfr Exp $
*/
/*
@@ -490,8 +490,8 @@ pipe_build_write_buffer(wpipe, uio)
if (size > wpipe->pipe_buffer.size)
size = wpipe->pipe_buffer.size;
- endaddr = round_page(uio->uio_iov->iov_base + size);
- for(i = 0, addr = trunc_page(uio->uio_iov->iov_base);
+ endaddr = round_page((vm_offset_t)uio->uio_iov->iov_base + size);
+ for(i = 0, addr = trunc_page((vm_offset_t)uio->uio_iov->iov_base);
addr < endaddr;
addr += PAGE_SIZE, i+=1) {
diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c
index 8aabc9a..edc74a7 100644
--- a/sys/kern/sysv_shm.c
+++ b/sys/kern/sysv_shm.c
@@ -1,4 +1,4 @@
-/* $Id: sysv_shm.c,v 1.37 1998/05/04 17:12:47 dyson Exp $ */
+/* $Id: sysv_shm.c,v 1.38 1998/08/24 08:39:38 dfr Exp $ */
/* $NetBSD: sysv_shm.c,v 1.23 1994/07/04 23:25:12 glass Exp $ */
/*
@@ -265,7 +265,7 @@ shmat(p, uap)
return EINVAL;
} else {
/* This is just a hint to vm_map_find() about where to put it. */
- attach_va = round_page(p->p_vmspace->vm_taddr + MAXTSIZ + MAXDSIZ);
+ attach_va = round_page((vm_offset_t)p->p_vmspace->vm_taddr + MAXTSIZ + MAXDSIZ);
}
shm_handle = shmseg->shm_internal;
@@ -501,8 +501,7 @@ shmget_allocate_segment(p, uap, mode)
* to.
*/
shm_handle->shm_object =
- vm_pager_allocate(OBJT_SWAP, 0, OFF_TO_IDX(size),
- VM_PROT_DEFAULT, 0);
+ vm_pager_allocate(OBJT_SWAP, 0, size, VM_PROT_DEFAULT, 0);
vm_object_clear_flag(shm_handle->shm_object, OBJ_ONEMAPPING);
vm_object_set_flag(shm_handle->shm_object, OBJ_NOSPLIT);
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 09e3afb..0fc7770 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -11,7 +11,7 @@
* 2. Absolutely no warranty of function or purpose is made by the author
* John S. Dyson.
*
- * $Id: vfs_bio.c,v 1.177 1998/09/25 17:34:49 peter Exp $
+ * $Id: vfs_bio.c,v 1.178 1998/09/26 00:12:35 dillon Exp $
*/
/*
@@ -668,7 +668,7 @@ brelse(struct buf * bp)
}
if ((bp->b_flags & B_INVAL) == 0) {
- pmap_qenter(trunc_page(bp->b_data), bp->b_pages, bp->b_npages);
+ pmap_qenter(trunc_page((vm_offset_t)bp->b_data), bp->b_pages, bp->b_npages);
}
}
if (bp->b_flags & (B_NOCACHE|B_ERROR)) {
@@ -1721,7 +1721,7 @@ allocbuf(struct buf * bp, int size)
bp->b_pages[i] = NULL;
vm_page_unwire(m);
}
- pmap_qremove((vm_offset_t) trunc_page(bp->b_data) +
+ pmap_qremove((vm_offset_t) trunc_page((vm_offset_t)bp->b_data) +
(desiredpages << PAGE_SHIFT), (bp->b_npages - desiredpages));
bp->b_npages = desiredpages;
}
@@ -1827,7 +1827,7 @@ allocbuf(struct buf * bp, int size)
if (bp->b_validend == 0)
bp->b_flags &= ~B_CACHE;
}
- bp->b_data = (caddr_t) trunc_page(bp->b_data);
+ bp->b_data = (caddr_t) trunc_page((vm_offset_t)bp->b_data);
bp->b_npages = curbpnpages;
pmap_qenter((vm_offset_t) bp->b_data,
bp->b_pages, bp->b_npages);
@@ -1975,7 +1975,7 @@ biodone(register struct buf * bp)
continue;
}
bp->b_pages[i] = m;
- pmap_qenter(trunc_page(bp->b_data), bp->b_pages, bp->b_npages);
+ pmap_qenter(trunc_page((vm_offset_t)bp->b_data), bp->b_pages, bp->b_npages);
}
#if defined(VFS_BIO_DEBUG)
if (OFF_TO_IDX(foff) != m->pindex) {
@@ -2123,7 +2123,7 @@ vfs_unbusy_pages(struct buf * bp)
}
#endif
bp->b_pages[i] = m;
- pmap_qenter(trunc_page(bp->b_data), bp->b_pages, bp->b_npages);
+ pmap_qenter(trunc_page((vm_offset_t)bp->b_data), bp->b_pages, bp->b_npages);
}
vm_object_pip_subtract(obj, 1);
vm_page_flag_clear(m, PG_ZERO);
@@ -2260,7 +2260,7 @@ retry:
else if (bp->b_bcount >= PAGE_SIZE) {
if (m->valid && (bp->b_flags & B_CACHE) == 0) {
bp->b_pages[i] = bogus_page;
- pmap_qenter(trunc_page(bp->b_data), bp->b_pages, bp->b_npages);
+ pmap_qenter(trunc_page((vm_offset_t)bp->b_data), bp->b_pages, bp->b_npages);
}
}
}
@@ -2349,7 +2349,7 @@ vm_hold_load_pages(struct buf * bp, vm_offset_t from, vm_offset_t to)
to = round_page(to);
from = round_page(from);
- index = (from - trunc_page(bp->b_data)) >> PAGE_SHIFT;
+ index = (from - trunc_page((vm_offset_t)bp->b_data)) >> PAGE_SHIFT;
for (pg = from; pg < to; pg += PAGE_SIZE, index++) {
@@ -2382,7 +2382,7 @@ vm_hold_free_pages(struct buf * bp, vm_offset_t from, vm_offset_t to)
from = round_page(from);
to = round_page(to);
- newnpages = index = (from - trunc_page(bp->b_data)) >> PAGE_SHIFT;
+ newnpages = index = (from - trunc_page((vm_offset_t)bp->b_data)) >> PAGE_SHIFT;
for (pg = from; pg < to; pg += PAGE_SIZE, index++) {
p = bp->b_pages[index];
diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c
index 40fc315..a5258d8 100644
--- a/sys/kern/vfs_export.c
+++ b/sys/kern/vfs_export.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95
- * $Id: vfs_subr.c,v 1.163 1998/09/14 19:56:40 sos Exp $
+ * $Id: vfs_subr.c,v 1.164 1998/10/12 20:14:09 dt Exp $
*/
/*
@@ -2539,15 +2539,14 @@ retry:
if (vp->v_type == VREG) {
if ((error = VOP_GETATTR(vp, &vat, cred, p)) != 0)
goto retn;
- object = vnode_pager_alloc(vp,
- OFF_TO_IDX(round_page(vat.va_size)), 0, 0);
+ object = vnode_pager_alloc(vp, vat.va_size, 0, 0);
} else if (major(vp->v_rdev) < nblkdev) {
/*
* This simply allocates the biggest object possible
* for a VBLK vnode. This should be fixed, but doesn't
* cause any problems (yet).
*/
- object = vnode_pager_alloc(vp, INT_MAX, 0, 0);
+ object = vnode_pager_alloc(vp, IDX_TO_OFF(INT_MAX), 0, 0);
}
object->ref_count--;
vp->v_usecount--;
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 40fc315..a5258d8 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95
- * $Id: vfs_subr.c,v 1.163 1998/09/14 19:56:40 sos Exp $
+ * $Id: vfs_subr.c,v 1.164 1998/10/12 20:14:09 dt Exp $
*/
/*
@@ -2539,15 +2539,14 @@ retry:
if (vp->v_type == VREG) {
if ((error = VOP_GETATTR(vp, &vat, cred, p)) != 0)
goto retn;
- object = vnode_pager_alloc(vp,
- OFF_TO_IDX(round_page(vat.va_size)), 0, 0);
+ object = vnode_pager_alloc(vp, vat.va_size, 0, 0);
} else if (major(vp->v_rdev) < nblkdev) {
/*
* This simply allocates the biggest object possible
* for a VBLK vnode. This should be fixed, but doesn't
* cause any problems (yet).
*/
- object = vnode_pager_alloc(vp, INT_MAX, 0, 0);
+ object = vnode_pager_alloc(vp, IDX_TO_OFF(INT_MAX), 0, 0);
}
object->ref_count--;
vp->v_usecount--;
OpenPOWER on IntegriCloud