qemu bug where load linux kernel
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
QEMU |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
i found a qemu bug ,when the qemu start and parse the kernel file .
This vulnerability can be exploited.
thanks
/****
(gdb) set args -nodefaults -device pc-testdev -device isa-debug-
(gdb) r
Starting program: /usr/bin/
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_
[New Thread 0x7fffe9a03700 (LWP 30066)]
[New Thread 0x7fffe9202700 (LWP 30068)]
[New Thread 0x7fffe8a01700 (LWP 30069)]
Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault.
__memmove_
249 ../sysdeps/
(gdb) bt
#0 0x00007ffff2390b1f in __memmove_
#1 0x00005555559ebdcf in rom_copy ()
#2 0x00005555558dd1b3 in load_multiboot ()
#3 0x00005555558de1c3 in ()
#4 0x00005555558e19d1 in pc_memory_init ()
#5 0x00005555558e4ee3 in ()
#6 0x00005555559e8500 in machine_
#7 0x0000555555834959 in main ()
(gdb) c
Continuing.
Couldn't get registers: No such process.
Couldn't get registers: No such process.
(gdb) [Thread 0x7fffe8a01700 (LWP 30069) exited]
[Thread 0x7fffe9202700 (LWP 30068) exited]
[Thread 0x7fffe9a03700 (LWP 30066) exited]
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
***/
Changed in qemu: | |
status: | Fix Committed → Fix Released |
information type: | Private Security → Public Security |
bug reason and how to fix it
/*
* Copies memory from registered ROMs to dest. Any memory that is contained in
* a ROM between addr and addr + size is copied. Note that this can involve
* multiple ROMs, which need not start at addr and need not end at addr + size.
*/
int rom_copy(uint8_t *dest, hwaddr addr, size_t size)
{
hwaddr end = addr + size;
uint8_t *s, *d = dest;
size_t l = 0;
Rom *rom;
QTAILQ_ FOREACH( rom, &roms, next) {
continue;
continue;
continue;
if (rom->fw_file) {
}
if (rom->mr) {
}
if (rom->addr + rom->romsize < addr) {
}
if (rom->addr > end) {
break;
}
d = dest + (rom->addr - addr);
s = rom->data;
l = rom->datasize;
if ((d + l) > (dest + size)) {
l = dest - d;
}
if (l > 0) {
memcpy( d, s, l); //*****crash here how to fix check the size l.******//
}
if (rom->romsize > rom->datasize) {
/* If datasize is less than romsize, it means that we didn't
* allocate all the ROM because the trailing data are only zeros.
*/
d += l;
l = rom->romsize - rom->datasize;
if ((d + l) > (dest + size)) {
/* Rom size doesn't fit in the destination area. Adjust to avoid
* overflow.
*/
l = dest - d;
}
if (l > 0) {
memset( d, 0x0, l);
}
}
}
return (d + l) - dest;
}