[SeaBIOS] SeaBIOS crashes on CBFS without legacy header
Kevin O'Connor
kevin at koconnor.net
Mon Dec 28 18:31:42 CET 2015
On Thu, Dec 24, 2015 at 03:45:03PM -0800, Alex Gagniuc wrote:
> When SeaBIOS is run on an FMAP-based CBFS (AKA, without a CBFS master
> header, it crashes). The problem is in coreboot_cbfs_init. A
> disassembly with -Mintel shows the following:
>
> 00000000 <coreboot_cbfs_init>:
> ...
> 7: 8b 35 fc ff ff ff mov esi,DWORD PTR ds:0xfffffffc
> d: 81 3e 4f 52 42 43 cmp DWORD PTR [esi],0x4342524f
>
> > 7: 8b 35 fc ff ff ff mov esi,DWORD PTR ds:0xfffffffc
>
> Move the contents of memory address 0xfffffffc to esi. Since there's
> no legacy CBFS pointer, the region is all 1's. esi now contains
> 0xffffffff
>
> > d: 81 3e 4f 52 42 43 cmp DWORD PTR [esi],0x4342524f
>
> 32-bit dereference esi (0xffffffff) -- causes general protection
> fault. The dereference is not because of unaligned access, but because
> the access goes over the 32-bit address space in flat mode. The way
> around this iss to sanitize the value at [0xffffffff] before
> dereferencing it. A sane check is:
>
> if(address_of_hdr > (0xfffffff0 - sizeof(*hdr)))
> fail();
> This is sane check because because the x86 reset vector is resides at
> 0xfffffff0 (there are cases where this isn't true, but that's besides
> the point here).
Thanks. Can you put together a patch, or do you want me to?
> There's also an unrelated problem with the C code that generates this assembly:
>
> > struct cbfs_header *hdr = *(void **)(CONFIG_CBFS_LOCATION - 4);
>
> With CONFIG_CBFS_LOCATION = 0, this places a negative value (-4) in an
> unsigned type (pointer). The behavior of this is undefined according
> to the C standard.
Are you suggesting that an (unsigned) cast should be added? I doubt
it would matter.
-Kevin
More information about the SeaBIOS
mailing list