- add a sanity check for e2fs_inode_size in readsb()

- use EXT2_DINODE_SIZE() rather than sizeof(struct ext2fs_dinode) or
  struct ext2fs_dinode array/pointer to see e2fs_ipb and inode offsets
This commit is contained in:
tsutsui 2009-03-02 11:31:59 +00:00
parent 14c85750c6
commit f592533590
2 changed files with 31 additions and 14 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: inode.c,v 1.27 2008/11/24 17:41:29 tsutsui Exp $ */ /* $NetBSD: inode.c,v 1.28 2009/03/02 11:31:59 tsutsui Exp $ */
/* /*
* Copyright (c) 1980, 1986, 1993 * Copyright (c) 1980, 1986, 1993
@ -63,7 +63,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)inode.c 8.5 (Berkeley) 2/8/95"; static char sccsid[] = "@(#)inode.c 8.5 (Berkeley) 2/8/95";
#else #else
__RCSID("$NetBSD: inode.c,v 1.27 2008/11/24 17:41:29 tsutsui Exp $"); __RCSID("$NetBSD: inode.c,v 1.28 2009/03/02 11:31:59 tsutsui Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -371,6 +371,7 @@ struct ext2fs_dinode *
ginode(ino_t inumber) ginode(ino_t inumber)
{ {
daddr_t iblk; daddr_t iblk;
struct ext2fs_dinode *dp;
if ((inumber < EXT2_FIRSTINO && if ((inumber < EXT2_FIRSTINO &&
inumber != EXT2_ROOTINO && inumber != EXT2_ROOTINO &&
@ -385,9 +386,13 @@ ginode(ino_t inumber)
if (pbp != 0) if (pbp != 0)
pbp->b_flags &= ~B_INUSE; pbp->b_flags &= ~B_INUSE;
pbp = getdatablk(iblk, sblock.e2fs_bsize); pbp = getdatablk(iblk, sblock.e2fs_bsize);
startinum = ((inumber -1) / sblock.e2fs_ipb) * sblock.e2fs_ipb + 1; startinum =
((inumber - 1) / sblock.e2fs_ipb) * sblock.e2fs_ipb + 1;
} }
return (&pbp->b_un.b_dinode[(inumber-1) % sblock.e2fs_ipb]); dp = (struct ext2fs_dinode *)(pbp->b_un.b_buf +
EXT2_DINODE_SIZE(&sblock) * ino_to_fsbo(&sblock, inumber));
return dp;
} }
/* /*
@ -396,14 +401,15 @@ ginode(ino_t inumber)
*/ */
ino_t nextino, lastinum; ino_t nextino, lastinum;
long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize; long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize;
struct ext2fs_dinode *inodebuf; char *inodebuf;
struct ext2fs_dinode * struct ext2fs_dinode *
getnextinode(ino_t inumber) getnextinode(ino_t inumber)
{ {
long size; long size;
daddr_t dblk; daddr_t dblk;
static struct ext2fs_dinode *dp; struct ext2fs_dinode *dp;
static char *bp;
if (inumber != nextino++ || inumber > maxino) if (inumber != nextino++ || inumber > maxino)
errexit("bad inode number %llu to nextinode", errexit("bad inode number %llu to nextinode",
@ -418,10 +424,13 @@ getnextinode(ino_t inumber)
size = inobufsize; size = inobufsize;
lastinum += fullcnt; lastinum += fullcnt;
} }
(void)bread(fsreadfd, (char *)inodebuf, dblk, size); (void)bread(fsreadfd, inodebuf, dblk, size);
dp = inodebuf; bp = inodebuf;
} }
return (dp++); dp = (struct ext2fs_dinode *)bp;
bp += EXT2_DINODE_SIZE(&sblock);
return dp;
} }
void void
@ -433,10 +442,10 @@ resetinodebuf(void)
lastinum = 1; lastinum = 1;
readcnt = 0; readcnt = 0;
inobufsize = blkroundup(&sblock, INOBUFSIZE); inobufsize = blkroundup(&sblock, INOBUFSIZE);
fullcnt = inobufsize / sizeof(struct ext2fs_dinode); fullcnt = inobufsize / EXT2_DINODE_SIZE(&sblock);
readpercg = sblock.e2fs.e2fs_ipg / fullcnt; readpercg = sblock.e2fs.e2fs_ipg / fullcnt;
partialcnt = sblock.e2fs.e2fs_ipg % fullcnt; partialcnt = sblock.e2fs.e2fs_ipg % fullcnt;
partialsize = partialcnt * sizeof(struct ext2fs_dinode); partialsize = partialcnt * EXT2_DINODE_SIZE(&sblock);
if (partialcnt != 0) { if (partialcnt != 0) {
readpercg++; readpercg++;
} else { } else {

View File

@ -1,4 +1,4 @@
/* $NetBSD: setup.c,v 1.25 2008/03/16 23:17:55 lukem Exp $ */ /* $NetBSD: setup.c,v 1.26 2009/03/02 11:31:59 tsutsui Exp $ */
/* /*
* Copyright (c) 1980, 1986, 1993 * Copyright (c) 1980, 1986, 1993
@ -63,7 +63,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)setup.c 8.5 (Berkeley) 11/23/94"; static char sccsid[] = "@(#)setup.c 8.5 (Berkeley) 11/23/94";
#else #else
__RCSID("$NetBSD: setup.c,v 1.25 2008/03/16 23:17:55 lukem Exp $"); __RCSID("$NetBSD: setup.c,v 1.26 2009/03/02 11:31:59 tsutsui Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -309,6 +309,14 @@ readsb(int listerr)
badsb(listerr, "BAD LOG_BSIZE"); badsb(listerr, "BAD LOG_BSIZE");
return 0; return 0;
} }
if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
(!powerof2(sblock.e2fs.e2fs_inode_size) ||
sblock.e2fs.e2fs_inode_size < sizeof(struct ext2fs_dinode) ||
sblock.e2fs.e2fs_inode_size >
(1024 << sblock.e2fs.e2fs_log_bsize))) {
badsb(listerr, "BAD INODE_SIZE");
return 0;
}
/* compute the dynamic fields of the in-memory sb */ /* compute the dynamic fields of the in-memory sb */
/* compute dynamic sb infos */ /* compute dynamic sb infos */
@ -323,7 +331,7 @@ readsb(int listerr)
sblock.e2fs_bmask = ~sblock.e2fs_qbmask; sblock.e2fs_bmask = ~sblock.e2fs_qbmask;
sblock.e2fs_ngdb = howmany(sblock.e2fs_ncg, sblock.e2fs_ngdb = howmany(sblock.e2fs_ncg,
sblock.e2fs_bsize / sizeof(struct ext2_gd)); sblock.e2fs_bsize / sizeof(struct ext2_gd));
sblock.e2fs_ipb = sblock.e2fs_bsize / sizeof(struct ext2fs_dinode); sblock.e2fs_ipb = sblock.e2fs_bsize / EXT2_DINODE_SIZE(&sblock);
sblock.e2fs_itpg = howmany(sblock.e2fs.e2fs_ipg, sblock.e2fs_ipb); sblock.e2fs_itpg = howmany(sblock.e2fs.e2fs_ipg, sblock.e2fs_ipb);
/* /*