commit 68ac426949170bb3802a6d610f366f24aa0bb734 Author: Ruediger Meier Date: Tue Jan 23 16:59:25 2018 +0100 fsck.cramfs: fix error message errno is invalid in case that we just read(3) too short. Signed-off-by: Ruediger Meier commit c990f94cbcc68c7bab47458a09e361ce0791b6d8 Author: Ruediger Meier Date: Tue Jan 23 16:59:24 2018 +0100 tests: rewrite fsck-bad-header Fix test for systems with pagesize != 4096 Loop over many combinations of sizes, endianness and blocksizes. Signed-off-by: Ruediger Meier commit 2374b1ab75c66c9ecea86fc97abb6d6c048bcf45 Author: Ruediger Meier Date: Tue Jan 23 16:59:23 2018 +0100 fsck.cramfs: fix crash when superblock size is too small This hopefully fixes the original problem addressed by the reverted patch 7cb962c7. The bug was introduced by myself in f991dbd3 "fsck.cramfs: allow smaller superblock sizes" CC: Tobias Stoeckmann Signed-off-by: Ruediger Meier commit 919e372da872bcc37502783e80564654569edb22 Author: Ruediger Meier Date: Tue Jan 23 16:59:22 2018 +0100 Revert "fsck.cramfs: Fix bus error on broken file system." This reverts commit 7cb962c77015e9383b53eeb22ce732cb5216bbc3. It can't be right that we mmap (start + super.size) bytes from a file which is usually only super.size bytes large. The patch "fixed" a problem when super.size is bad but now it fails for the correct case: $ mkdir -p root/subdir $ ./mkfs.cramfs -p root cramfs $ ./fsck.cramfs cramfs Bus error (core dumped) We will fix the original problem later. CC: Tobias Stoeckmann Signed-off-by: Ruediger Meier diff -urN util-linux-2.31.1.orig/disk-utils/fsck.cramfs.c util-linux-2.31.1/disk-utils/fsck.cramfs.c --- util-linux-2.31.1.orig/disk-utils/fsck.cramfs.c 2017-12-14 15:26:35.141144200 +0100 +++ util-linux-2.31.1/disk-utils/fsck.cramfs.c 2018-01-26 18:41:01.001095311 +0100 @@ -192,7 +192,7 @@ errx(FSCK_EX_ERROR, _("unsupported filesystem features")); /* What are valid superblock sizes? */ - if (super.size < sizeof(struct cramfs_super)) + if (super.size < *start + sizeof(struct cramfs_super)) errx(FSCK_EX_UNCORRECTED, _("superblock size (%d) too small"), super.size); @@ -220,24 +220,28 @@ crc = crc32(0L, NULL, 0); buf = - mmap(NULL, start + super.size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + mmap(NULL, super.size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (buf == MAP_FAILED) { buf = - mmap(NULL, start + super.size, PROT_READ | PROT_WRITE, + mmap(NULL, super.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (buf != MAP_FAILED) { - if (lseek(fd, start, SEEK_SET) == (off_t) -1) + ssize_t tmp; + if (lseek(fd, 0, SEEK_SET) == (off_t) -1) err(FSCK_EX_ERROR, _("seek on %s failed"), filename); - if (read(fd, (unsigned char *) buf + start, super.size) != - (ssize_t) super.size) + tmp = read(fd, buf, super.size); + if (tmp < 0) err(FSCK_EX_ERROR, _("cannot read %s"), filename); + if (tmp != (ssize_t) super.size) + errx(FSCK_EX_ERROR, _("failed to read %"PRIu32" bytes from file %s"), + super.size, filename); } } if (buf != MAP_FAILED) { ((struct cramfs_super *)((unsigned char *) buf + start))->fsid.crc = crc32(0L, NULL, 0); - crc = crc32(crc, (unsigned char *) buf + start, super.size); - munmap(buf, start + super.size); + crc = crc32(crc, (unsigned char *) buf + start, super.size - start); + munmap(buf, super.size); } else { int retval; size_t length = 0; diff -urN util-linux-2.31.1.orig/tests/expected/cramfs/fsck-bad-header util-linux-2.31.1/tests/expected/cramfs/fsck-bad-header --- util-linux-2.31.1.orig/tests/expected/cramfs/fsck-bad-header 2017-12-14 15:26:46.585066844 +0100 +++ util-linux-2.31.1/tests/expected/cramfs/fsck-bad-header 1970-01-01 01:00:00.000000000 +0100 @@ -1,2 +0,0 @@ -fsck.cramfs: file extends past end of filesystem -fsck.cramfs: crc error diff -urN util-linux-2.31.1.orig/tests/expected/cramfs/fsck-bad-header-nopad-4K-be util-linux-2.31.1/tests/expected/cramfs/fsck-bad-header-nopad-4K-be --- util-linux-2.31.1.orig/tests/expected/cramfs/fsck-bad-header-nopad-4K-be 1970-01-01 01:00:00.000000000 +0100 +++ util-linux-2.31.1/tests/expected/cramfs/fsck-bad-header-nopad-4K-be 2018-01-26 18:40:57.401031690 +0100 @@ -0,0 +1,29 @@ +## size: 0 +fsck.cramfs: superblock size (0) too small +ret: 4 + +## size: 75 +fsck.cramfs: superblock size (75) too small +ret: 4 + +## size: 76 +fsck.cramfs: file extends past end of filesystem +fsck.cramfs: crc error +ret: 4 + +## size: 4095 +fsck.cramfs: file extends past end of filesystem +fsck.cramfs: crc error +ret: 4 + +## size: 4096 +ret: 0 + +## size: 4097 +fsck.cramfs: file length too short +ret: 4 + +## size: 4294967295 +fsck.cramfs: file length too short +ret: 4 + diff -urN util-linux-2.31.1.orig/tests/expected/cramfs/fsck-bad-header-nopad-4K-le util-linux-2.31.1/tests/expected/cramfs/fsck-bad-header-nopad-4K-le --- util-linux-2.31.1.orig/tests/expected/cramfs/fsck-bad-header-nopad-4K-le 1970-01-01 01:00:00.000000000 +0100 +++ util-linux-2.31.1/tests/expected/cramfs/fsck-bad-header-nopad-4K-le 2018-01-26 18:40:57.401031690 +0100 @@ -0,0 +1,29 @@ +## size: 0 +fsck.cramfs: superblock size (0) too small +ret: 4 + +## size: 75 +fsck.cramfs: superblock size (75) too small +ret: 4 + +## size: 76 +fsck.cramfs: file extends past end of filesystem +fsck.cramfs: crc error +ret: 4 + +## size: 4095 +fsck.cramfs: file extends past end of filesystem +fsck.cramfs: crc error +ret: 4 + +## size: 4096 +ret: 0 + +## size: 4097 +fsck.cramfs: file length too short +ret: 4 + +## size: 4294967295 +fsck.cramfs: file length too short +ret: 4 + diff -urN util-linux-2.31.1.orig/tests/expected/cramfs/fsck-bad-header-pad-4K-be util-linux-2.31.1/tests/expected/cramfs/fsck-bad-header-pad-4K-be --- util-linux-2.31.1.orig/tests/expected/cramfs/fsck-bad-header-pad-4K-be 1970-01-01 01:00:00.000000000 +0100 +++ util-linux-2.31.1/tests/expected/cramfs/fsck-bad-header-pad-4K-be 2018-01-26 18:40:57.401031690 +0100 @@ -0,0 +1,29 @@ +## size: 76 +fsck.cramfs: superblock size (76) too small +ret: 4 + +## size: 587 +fsck.cramfs: superblock size (587) too small +ret: 4 + +## size: 588 +fsck.cramfs: file extends past end of filesystem +fsck.cramfs: crc error +ret: 4 + +## size: 4095 +fsck.cramfs: file extends past end of filesystem +fsck.cramfs: crc error +ret: 4 + +## size: 4096 +ret: 0 + +## size: 4097 +fsck.cramfs: file length too short +ret: 4 + +## size: 4294967295 +fsck.cramfs: file length too short +ret: 4 + diff -urN util-linux-2.31.1.orig/tests/expected/cramfs/fsck-bad-header-pad-4K-le util-linux-2.31.1/tests/expected/cramfs/fsck-bad-header-pad-4K-le --- util-linux-2.31.1.orig/tests/expected/cramfs/fsck-bad-header-pad-4K-le 1970-01-01 01:00:00.000000000 +0100 +++ util-linux-2.31.1/tests/expected/cramfs/fsck-bad-header-pad-4K-le 2018-01-26 18:40:57.401031690 +0100 @@ -0,0 +1,29 @@ +## size: 76 +fsck.cramfs: superblock size (76) too small +ret: 4 + +## size: 587 +fsck.cramfs: superblock size (587) too small +ret: 4 + +## size: 588 +fsck.cramfs: file extends past end of filesystem +fsck.cramfs: crc error +ret: 4 + +## size: 4095 +fsck.cramfs: file extends past end of filesystem +fsck.cramfs: crc error +ret: 4 + +## size: 4096 +ret: 0 + +## size: 4097 +fsck.cramfs: file length too short +ret: 4 + +## size: 4294967295 +fsck.cramfs: file length too short +ret: 4 + diff -urN util-linux-2.31.1.orig/tests/expected/cramfs/fsck-bad-header-pad-64K-be util-linux-2.31.1/tests/expected/cramfs/fsck-bad-header-pad-64K-be --- util-linux-2.31.1.orig/tests/expected/cramfs/fsck-bad-header-pad-64K-be 1970-01-01 01:00:00.000000000 +0100 +++ util-linux-2.31.1/tests/expected/cramfs/fsck-bad-header-pad-64K-be 2018-01-26 18:40:57.401031690 +0100 @@ -0,0 +1,29 @@ +## size: 76 +fsck.cramfs: superblock size (76) too small +ret: 4 + +## size: 587 +fsck.cramfs: superblock size (587) too small +ret: 4 + +## size: 588 +fsck.cramfs: file extends past end of filesystem +fsck.cramfs: crc error +ret: 4 + +## size: 65535 +fsck.cramfs: file extends past end of filesystem +fsck.cramfs: crc error +ret: 4 + +## size: 65536 +ret: 0 + +## size: 65537 +fsck.cramfs: file length too short +ret: 4 + +## size: 4294967295 +fsck.cramfs: file length too short +ret: 4 + diff -urN util-linux-2.31.1.orig/tests/expected/cramfs/fsck-bad-header-pad-64K-le util-linux-2.31.1/tests/expected/cramfs/fsck-bad-header-pad-64K-le --- util-linux-2.31.1.orig/tests/expected/cramfs/fsck-bad-header-pad-64K-le 1970-01-01 01:00:00.000000000 +0100 +++ util-linux-2.31.1/tests/expected/cramfs/fsck-bad-header-pad-64K-le 2018-01-26 18:40:57.401031690 +0100 @@ -0,0 +1,29 @@ +## size: 76 +fsck.cramfs: superblock size (76) too small +ret: 4 + +## size: 587 +fsck.cramfs: superblock size (587) too small +ret: 4 + +## size: 588 +fsck.cramfs: file extends past end of filesystem +fsck.cramfs: crc error +ret: 4 + +## size: 65535 +fsck.cramfs: file extends past end of filesystem +fsck.cramfs: crc error +ret: 4 + +## size: 65536 +ret: 0 + +## size: 65537 +fsck.cramfs: file length too short +ret: 4 + +## size: 4294967295 +fsck.cramfs: file length too short +ret: 4 + diff -urN util-linux-2.31.1.orig/tests/ts/cramfs/fsck-bad-header util-linux-2.31.1/tests/ts/cramfs/fsck-bad-header --- util-linux-2.31.1.orig/tests/ts/cramfs/fsck-bad-header 2017-12-14 15:26:46.585066844 +0100 +++ util-linux-2.31.1/tests/ts/cramfs/fsck-bad-header 2018-01-26 18:40:57.401031690 +0100 @@ -16,7 +16,7 @@ # GNU General Public License for more details. # TS_TOPDIR="${0%/*}/../.." -TS_DESC="fsck endianness" +TS_DESC="fsck bad header" . $TS_TOPDIR/functions.sh ts_init "$*" @@ -25,14 +25,78 @@ ts_check_test_command "$TS_CMD_FSCKCRAMFS" ts_check_prog "dd" -IMAGE_SOURCE="$TS_OUTDIR/${TS_TESTNAME}-data/root" +function num2binary() +{ + local num=$1 + local endian=$2 + + test "$num" -ge 0 -a "$num" -le 4294967295 || return 1 + test "$endian" = "be" -o "$endian" = "le" || return 1 + + # how to do that easier? + if test "$endian" = "be"; then + echo -en "$(printf "%08x" "$1" | sed 's/\(..\)/\\x\1/g')" + else + echo -en "$(printf "%08x" "$1" | sed 's/^\(..\)\(..\)\(..\)\(..\)$/\\x\4\\x\3\\x\2\\x\1/')" + fi +} + +function fsck_loop_sizes() +{ + local endian=$1 # be, le + local seek=$2 # 4 for nopad, 516 for pad + shift 2 # the rest are sizes to loop over + + for size in "$@"; do + ts_log "## size: $size" + cp -a "$IMAGE_FILE" "$IMAGE_FILE.tmp" + num2binary "$size" $endian | + dd of="$IMAGE_FILE.tmp" bs=1 seek="$seek" count=4 conv=notrunc &> /dev/null + $TS_CMD_FSCKCRAMFS "$IMAGE_FILE.tmp" >> $TS_OUTPUT 2>&1 + ts_log "ret: $? +" + done + rm -f "$IMAGE_FILE" +} + + +IMAGE_SOURCE="$TS_OUTDIR/${TS_TESTNAME}-data" IMAGE_FILE="$TS_OUTDIR/${TS_TESTNAME}-cramfs.img" mkdir -p "${IMAGE_SOURCE}/subdir" &> /dev/null -$TS_CMD_MKCRAMFS -p -N big $IMAGE_SOURCE $IMAGE_FILE &> /dev/null -echo -ne \\00\\x4c | - dd of=$IMAGE_FILE bs=1 seek=518 count=2 conv=notrunc &> /dev/null -$TS_CMD_FSCKCRAMFS $IMAGE_FILE >> $TS_OUTPUT 2>&1 + +ts_init_subtest "nopad-4K-be" +$TS_CMD_MKCRAMFS -N big -b 4096 $IMAGE_SOURCE $IMAGE_FILE &> /dev/null +fsck_loop_sizes be 4 0 75 76 4095 4096 4097 4294967295 +rm -f "$IMAGE_FILE" +ts_finalize_subtest + +ts_init_subtest "nopad-4K-le" +$TS_CMD_MKCRAMFS -N little -b 4096 $IMAGE_SOURCE $IMAGE_FILE &> /dev/null +fsck_loop_sizes le 4 0 75 76 4095 4096 4097 4294967295 +ts_finalize_subtest + +ts_init_subtest "pad-4K-be" +$TS_CMD_MKCRAMFS -p -N big -b 4096 $IMAGE_SOURCE $IMAGE_FILE &> /dev/null +fsck_loop_sizes be 516 76 587 588 4095 4096 4097 4294967295 +ts_finalize_subtest + +ts_init_subtest "pad-4K-le" +$TS_CMD_MKCRAMFS -p -N little -b 4096 $IMAGE_SOURCE $IMAGE_FILE &> /dev/null +fsck_loop_sizes le 516 76 587 588 4095 4096 4097 4294967295 +ts_finalize_subtest + +ts_init_subtest "pad-64K-be" +$TS_CMD_MKCRAMFS -p -N big -b 65536 $IMAGE_SOURCE $IMAGE_FILE &> /dev/null +fsck_loop_sizes be 516 76 587 588 65535 65536 65537 4294967295 +ts_finalize_subtest + +ts_init_subtest "pad-64K-le" +$TS_CMD_MKCRAMFS -p -N little -b 65536 $IMAGE_SOURCE $IMAGE_FILE &> /dev/null +fsck_loop_sizes le 516 76 587 588 65535 65536 65537 4294967295 +ts_finalize_subtest + +rm -rf "$IMAGE_SOURCE" "$IMAGE_FILE.tmp" ts_finalize