diff options
author | Otto Moerbeek <otto@cvs.openbsd.org> | 2007-02-08 13:09:54 +0000 |
---|---|---|
committer | Otto Moerbeek <otto@cvs.openbsd.org> | 2007-02-08 13:09:54 +0000 |
commit | 352d740dd85eb470c920da7405b235e0849a6c80 (patch) | |
tree | 72a879e1aad1163becc30a0a6a03cc4441f7754a /sbin/fsck_ffs/dir.c | |
parent | 83c0b73cc9d650c2620c0a1e32d9e6d8d7b14c61 (diff) |
A corrrup inode might lead to preposterous dir sizes. So check the
size to avoid a negative lastbn which might cause a segv or heap
corruption. With help from mickey@; ok mickey@ pedro@ millert@
Diffstat (limited to 'sbin/fsck_ffs/dir.c')
-rw-r--r-- | sbin/fsck_ffs/dir.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/sbin/fsck_ffs/dir.c b/sbin/fsck_ffs/dir.c index 1d014c74eca..0b2cd296680 100644 --- a/sbin/fsck_ffs/dir.c +++ b/sbin/fsck_ffs/dir.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dir.c,v 1.18 2007/01/24 13:24:58 bluhm Exp $ */ +/* $OpenBSD: dir.c,v 1.19 2007/02/08 13:09:53 otto Exp $ */ /* $NetBSD: dir.c,v 1.20 1996/09/27 22:45:11 christos Exp $ */ /* @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)dir.c 8.5 (Berkeley) 12/8/94"; #else -static const char rcsid[] = "$OpenBSD: dir.c,v 1.18 2007/01/24 13:24:58 bluhm Exp $"; +static const char rcsid[] = "$OpenBSD: dir.c,v 1.19 2007/02/08 13:09:53 otto Exp $"; #endif #endif /* not lint */ @@ -555,8 +555,12 @@ expanddir(struct ufs1_dinode *dp, char *name) daddr_t lastbn, newblk; struct bufarea *bp; char *cp, firstblk[DIRBLKSIZ]; + u_int64_t dis; - lastbn = lblkno(&sblock, dp->di_size); + dis = lblkno(&sblock, dp->di_size); + if (dis > (u_int64_t)INT_MAX) + return (0); + lastbn = dis; if (lastbn >= NDADDR - 1 || dp->di_db[lastbn] == 0 || dp->di_size == 0) return (0); if ((newblk = allocblk(sblock.fs_frag)) == 0) |