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>
This commit is contained in:
parent
8175ed3d74
commit
7cb962c770
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue