From 41e20344a2c6be15ca2241c5ba2d72d984a96456 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Sat, 30 Nov 2002 18:28:26 +0000 Subject: [PATCH] Add some more checks to newfs so that it will not build filesystems that the kernel will refuse to mount. Specifically it now enforces the MAXBSIZE blocksize limit. This update also fixes a problem where newfs could segment fault if the selected fragment size was too large. PR: bin/30959 Submitted by: Ceri Davies Sponsored by: DARPA & NAI Labs. --- sbin/newfs/mkfs.c | 38 ++++++++++++++++++++++++-------------- sbin/newfs/newfs.c | 6 +++++- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/sbin/newfs/mkfs.c b/sbin/newfs/mkfs.c index 837f608d2855..625efb5ab76f 100644 --- a/sbin/newfs/mkfs.c +++ b/sbin/newfs/mkfs.c @@ -136,19 +136,6 @@ mkfs(struct partition *pp, char *fsys) randinit = 1; srandomdev(); } - /* - * allocate space for superblock, cylinder group map, and - * two sets of inode blocks. - */ - if (bsize < SBLOCKSIZE) - iobufsize = SBLOCKSIZE + 3 * bsize; - else - iobufsize = 4 * bsize; - if ((iobuf = malloc(iobufsize)) == 0) { - printf("Cannot allocate I/O buffer\n"); - exit(38); - } - bzero(iobuf, iobufsize); sblock.fs_old_flags = FS_FLAGS_UPDATED; sblock.fs_flags = 0; if (Uflag) @@ -195,11 +182,21 @@ mkfs(struct partition *pp, char *fsys) sblock.fs_fsize, sectorsize); sblock.fs_fsize = sectorsize; } + if (sblock.fs_bsize > MAXBSIZE) { + printf("decreasing block size from %d to maximum (%d)\n", + sblock.fs_bsize, MAXBSIZE); + sblock.fs_bsize = MAXBSIZE; + } if (sblock.fs_bsize < MINBSIZE) { printf("increasing block size from %d to minimum (%d)\n", sblock.fs_bsize, MINBSIZE); sblock.fs_bsize = MINBSIZE; } + if (sblock.fs_fsize > MAXBSIZE) { + printf("decreasing fragment size from %d to maximum (%d)\n", + sblock.fs_fsize, MAXBSIZE); + sblock.fs_fsize = MAXBSIZE; + } if (sblock.fs_bsize < sblock.fs_fsize) { printf("increasing block size from %d to fragment size (%d)\n", sblock.fs_bsize, sblock.fs_fsize); @@ -297,7 +294,7 @@ mkfs(struct partition *pp, char *fsys) */ origdensity = density; for (;;) { - fragsperinode = numfrags(&sblock, density); + fragsperinode = MAX(numfrags(&sblock, density), 1); minfpg = fragsperinode * INOPB(&sblock); if (minfpg > sblock.fs_size) minfpg = sblock.fs_size; @@ -443,6 +440,19 @@ mkfs(struct partition *pp, char *fsys) printf("super-block backups (for fsck -b #) at:\n"); i = 0; width = charsperline(); + /* + * allocate space for superblock, cylinder group map, and + * two sets of inode blocks. + */ + if (sblock.fs_bsize < SBLOCKSIZE) + iobufsize = SBLOCKSIZE + 3 * sblock.fs_bsize; + else + iobufsize = 4 * sblock.fs_bsize; + if ((iobuf = malloc(iobufsize)) == 0) { + printf("Cannot allocate I/O buffer\n"); + exit(38); + } + bzero(iobuf, iobufsize); /* * Make a copy of the superblock into the buffer that we will be * writing out in each cylinder group. diff --git a/sbin/newfs/newfs.c b/sbin/newfs/newfs.c index 8b03e9420e19..50034a2bda05 100644 --- a/sbin/newfs/newfs.c +++ b/sbin/newfs/newfs.c @@ -187,7 +187,11 @@ main(int argc, char *argv[]) break; case 'b': if ((bsize = atoi(optarg)) < MINBSIZE) - errx(1, "%s: bad block size", optarg); + errx(1, "%s: block size too small, min is %d", + optarg, MINBSIZE); + if (bsize > MAXBSIZE) + errx(1, "%s: block size too large, max is %d", + optarg, MAXBSIZE); break; case 'c': if ((maxblkspercg = atoi(optarg)) <= 0)