NetBSD-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Unable to fsck 4.5TB FFSv2 fs
On Sep 25, 12:15pm, netbsd%precedence.co.uk@localhost (Stephen Borrill) wrote:
-- Subject: Re: Unable to fsck 4.5TB FFSv2 fs
| ** /dev/rld1d
| ** Last Mounted on /usr/backup
| ** Phase 1 - Check Blocks and Sizes
| cannot alloc 4294967292 bytes for inoinfo
that is 0xfffffffc which looks very fishy. This patch adds overflow detection,
can you test it?
Index: pass1.c
===================================================================
RCS file: /cvsroot/src/sbin/fsck_ffs/pass1.c,v
retrieving revision 1.44
diff -u -u -r1.44 pass1.c
--- pass1.c 23 Feb 2008 21:41:48 -0000 1.44
+++ pass1.c 25 Sep 2008 15:47:20 -0000
@@ -66,7 +66,8 @@
void
pass1(void)
{
- ino_t inumber, inosused;
+ ino_t inumber, inosused, ninosused;
+ size_t inospace;
int c;
daddr_t i, cgd;
struct inodesc idesc;
@@ -151,12 +152,19 @@
inostathead[c].il_stat = 0;
continue;
}
- info = calloc((unsigned)inosused, sizeof(struct inostat));
+ inospace = inosused * sizeof(*info);
+ if (inospace / sizeof(*info) != inosused) {
+ pfatal("too many inodes %llu\n", (unsigned long long)
+ inosused);
+ exit(FSCK_EXIT_CHECK_FAILED);
+ }
+ info = malloc(inospace);
if (info == NULL) {
- pfatal("cannot alloc %u bytes for inoinfo\n",
- (unsigned)(sizeof(struct inostat) * inosused));
+ pfatal("cannot alloc %zu bytes for inoinfo\n",
+ inospace);
exit(FSCK_EXIT_CHECK_FAILED);
}
+ (void)memset(info, 0, inospace);
inostathead[c].il_stat = info;
/*
* Scan the allocated inodes.
@@ -178,24 +186,33 @@
* really found.
*/
if (lastino < (c * sblock->fs_ipg))
- inosused = 0;
+ ninosused = 0;
else
- inosused = lastino - (c * sblock->fs_ipg);
- inostathead[c].il_numalloced = inosused;
- if (inosused == 0) {
+ ninosused = lastino - (c * sblock->fs_ipg);
+ inostathead[c].il_numalloced = ninosused;
+ if (ninosused == 0) {
free(inostathead[c].il_stat);
inostathead[c].il_stat = 0;
continue;
}
- info = calloc((unsigned)inosused, sizeof(struct inostat));
- if (info == NULL) {
- pfatal("cannot alloc %u bytes for inoinfo\n",
- (unsigned)(sizeof(struct inostat) * inosused));
- exit(FSCK_EXIT_CHECK_FAILED);
+ if (ninosused != inosused) {
+ struct inostat *ninfo;
+ size_t ninospace = ninosused * sizeof(*ninfo);
+ if (ninospace / sizeof(*info) != ninosused) {
+ pfatal("too many inodes %llu\n",
+ (unsigned long long)ninosused);
+ exit(FSCK_EXIT_CHECK_FAILED);
+ }
+ ninfo = realloc(info, ninosused);
+ if (ninfo == NULL) {
+ pfatal("cannot realloc %zu bytes to %zu "
+ "for inoinfo\n", inospace, ninospace);
+ exit(FSCK_EXIT_CHECK_FAILED);
+ }
+ if (ninosused > inosused)
+ (void)memset(&ninfo[inosused], 0, ninospace -
inospace);
+ inostathead[c].il_stat = ninfo;
}
- memmove(info, inostathead[c].il_stat, inosused * sizeof(*info));
- free(inostathead[c].il_stat);
- inostathead[c].il_stat = info;
}
#ifdef PROGRESS
if (!preen)
Home |
Main Index |
Thread Index |
Old Index