summaryrefslogtreecommitdiffstats
path: root/disk-utils
diff options
context:
space:
mode:
authorTobias Stoeckmann2017-10-30 13:49:53 +0100
committerKarel Zak2017-11-02 13:56:14 +0100
commit7cb962c77015e9383b53eeb22ce732cb5216bbc3 (patch)
tree106a8667441779e354cddae0ab388af167b83705 /disk-utils
parentsfdisk: allow to disable bootable flag on all partitions (diff)
downloadkernel-qcow2-util-linux-7cb962c77015e9383b53eeb22ce732cb5216bbc3.tar.gz
kernel-qcow2-util-linux-7cb962c77015e9383b53eeb22ce732cb5216bbc3.tar.xz
kernel-qcow2-util-linux-7cb962c77015e9383b53eeb22ce732cb5216bbc3.zip
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>
Diffstat (limited to 'disk-utils')
-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;