fix a bug of lfs.

genfs_getpages() can read in more blocks than it should due to faked filesize
of lfs_gop_size().  it's a security problem and it makes gcc3 "internal error"

to fix this,
- in genfs_getpages(), always calculate diskeof and memeof separately
  so that filesystems (in this case, lfs) can use different strategies
  for them.
- introduce GOP_SIZE_MEM flag and use it to request in-core filesize.
  (it was an intention of GOP_SIZE_READ,
  but after the above change _READ is not a straightforward name)

after this, no one uses GOP_SIZE_{READ,WRITE} anymore but leave them for now.
This commit is contained in:
yamt 2003-09-24 10:22:53 +00:00
parent 7242c1114c
commit 61d5d4362b
3 changed files with 11 additions and 10 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: genfs_node.h,v 1.4 2003/02/17 23:48:10 perseant Exp $ */
/* $NetBSD: genfs_node.h,v 1.5 2003/09/24 10:22:53 yamt Exp $ */
/*
* Copyright (c) 2001 Chuck Silvers.
@ -49,8 +49,9 @@ struct genfs_ops {
(*VTOG(vp)->g_op->gop_write)((vp), (pgs), (npages), (flags))
/* Flags to GOP_SIZE */
#define GOP_SIZE_READ 0x1 /* Advise how many pages to read/create */
#define GOP_SIZE_WRITE 0x2 /* Tell how many pages to write */
#define GOP_SIZE_READ 0x1 /* Advise how many pages to read */
#define GOP_SIZE_WRITE 0x2 /* Tell how many pages to write */
#define GOP_SIZE_MEM 0x4 /* in-memory size */
struct genfs_node {
struct genfs_ops *g_op; /* ops vector */

View File

@ -1,4 +1,4 @@
/* $NetBSD: genfs_vnops.c,v 1.81 2003/08/07 16:32:35 agc Exp $ */
/* $NetBSD: genfs_vnops.c,v 1.82 2003/09/24 10:22:53 yamt Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.81 2003/08/07 16:32:35 agc Exp $");
__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.82 2003/09/24 10:22:53 yamt Exp $");
#include "opt_nfsserver.h"
@ -499,9 +499,9 @@ genfs_getpages(void *v)
if (flags & PGO_PASTEOF) {
newsize = MAX(vp->v_size,
origoffset + (orignpages << PAGE_SHIFT));
GOP_SIZE(vp, newsize, &memeof, GOP_SIZE_READ);
GOP_SIZE(vp, newsize, &memeof, GOP_SIZE_READ|GOP_SIZE_MEM);
} else {
memeof = diskeof;
GOP_SIZE(vp, vp->v_size, &memeof, GOP_SIZE_READ|GOP_SIZE_MEM);
}
KASSERT(ap->a_centeridx >= 0 || ap->a_centeridx <= orignpages);
KASSERT((origoffset & (PAGE_SIZE - 1)) == 0 && origoffset >= 0);

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_vnops.c,v 1.117 2003/09/23 05:26:50 yamt Exp $ */
/* $NetBSD: lfs_vnops.c,v 1.118 2003/09/24 10:22:54 yamt Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.117 2003/09/23 05:26:50 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.118 2003/09/24 10:22:54 yamt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -1943,7 +1943,7 @@ lfs_gop_size(struct vnode *vp, off_t size, off_t *eobp, int flags)
olbn = lblkno(fs, ip->i_size);
nlbn = lblkno(fs, size);
if ((flags & GOP_SIZE_WRITE) && nlbn < NDADDR && olbn <= nlbn) {
if (!(flags & GOP_SIZE_MEM) && nlbn < NDADDR && olbn <= nlbn) {
*eobp = fragroundup(fs, size);
} else {
*eobp = blkroundup(fs, size);