summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Stoeckmann <tobias@stoeckmann.org>2017-10-30 13:49:53 +0100
committerKarel Zak <kzak@redhat.com>2017-12-14 15:26:35 +0100
commit4906ccc4e6df0b77ab65a8b7973d7531bacdf481 (patch)
tree7adde6660a33ed03ea0ba54eee8d2abe15406bc8
parent6b13880f365b78329e5423426617f0bf12bab326 (diff)
downloadutil-linux-4906ccc4e6df0b77ab65a8b7973d7531bacdf481.tar.gz
fsck.cramfs: Fix bus error on broken file system.
The utility fsck.cramfs is prone to a bus error on file systems for big endian systems with non-standard header sizes. While calculating the crc32 checksum, it does not properly handle a possible offset for bootcodes, resulting in out of boundary access of mmap'ed area. You can trigger the issue with the following commands: $ mkdir -p cramfs-poc/root/subdir $ cd cramfs-poc $ mkfs.cramfs -p -N big root cramfs $ echo -ne \\00\\x4c | dd of=cramfs bs=1 seek=518 count=2 conv=notrunc $ fsck.cramfs cramfs Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
-rw-r--r--disk-utils/fsck.cramfs.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/disk-utils/fsck.cramfs.c b/disk-utils/fsck.cramfs.c
index 50c7d33b9..b2a3cc153 100644
--- a/disk-utils/fsck.cramfs.c
+++ b/disk-utils/fsck.cramfs.c
@@ -220,23 +220,24 @@ static void test_crc(int start)
crc = crc32(0L, NULL, 0);
buf =
- mmap(NULL, super.size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ mmap(NULL, start + super.size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (buf == MAP_FAILED) {
buf =
- mmap(NULL, super.size, PROT_READ | PROT_WRITE,
+ mmap(NULL, start + super.size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (buf != MAP_FAILED) {
- if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
+ if (lseek(fd, start, SEEK_SET) == (off_t) -1)
err(FSCK_EX_ERROR, _("seek on %s failed"), filename);
- if (read(fd, buf, super.size) != (ssize_t) super.size)
+ if (read(fd, (unsigned char *) buf + start, super.size) !=
+ (ssize_t) super.size)
err(FSCK_EX_ERROR, _("cannot read %s"), 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 - start);
- munmap(buf, super.size);
+ crc = crc32(crc, (unsigned char *) buf + start, super.size);
+ munmap(buf, start + super.size);
} else {
int retval;
size_t length = 0;