Verify Option ROM contents */
| 808 | |
| 809 | /* Verify Option ROM contents */ |
| 810 | static int is_valid_vbios(const struct fileobject *fo) |
| 811 | { |
| 812 | if (fo->size > 64 * 2 * KiB) { |
| 813 | printerr("VBIOS is too big\n"); |
| 814 | return 0; |
| 815 | } |
| 816 | |
| 817 | if (fo->size < sizeof(optionrom_header_t)) { |
| 818 | printerr("VBIOS is too small\n"); |
| 819 | return 0; |
| 820 | } |
| 821 | |
| 822 | const optionrom_header_t *oh = (const optionrom_header_t *)fo->data; |
| 823 | |
| 824 | if (oh->signature != 0xaa55) { |
| 825 | printerr("bad oprom signature: 0x%x\n", oh->signature); |
| 826 | return 0; |
| 827 | } |
| 828 | |
| 829 | if (oh->size == 0 || oh->size > 0x80 || oh->size * 512 > fo->size) { |
| 830 | printerr("bad oprom size: 0x%x\n", oh->size); |
| 831 | return 0; |
| 832 | } |
| 833 | |
| 834 | const u8 cksum = checksum_vbios(oh); |
| 835 | if (cksum) { |
| 836 | if (!ignore_checksum) { |
| 837 | printerr("bad oprom checksum: 0x%x\n", cksum); |
| 838 | return 0; |
| 839 | } |
| 840 | printwarn("bad oprom checksum: 0x%x\n", cksum); |
| 841 | } |
| 842 | |
| 843 | if (oh->pcir_offset + sizeof(optionrom_pcir_t) > fo->size) { |
| 844 | printerr("bad pcir offset: 0x%x\n", oh->pcir_offset); |
| 845 | return 0; |
| 846 | } |
| 847 | |
| 848 | if (oh->pcir_offset) { |
| 849 | const optionrom_pcir_t *pcir; |
| 850 | pcir = (const optionrom_pcir_t *) |
| 851 | ((const u8 *)oh + oh->pcir_offset); |
| 852 | |
| 853 | if (pcir->signature != 0x52494350) { |
| 854 | printerr("Invalid PCIR signature\n"); |
| 855 | return 0; |
| 856 | } |
| 857 | |
| 858 | if (pcir->vendor != 0x8086) { |
| 859 | printerr("Not an Intel VBIOS\n"); |
| 860 | return 0; |
| 861 | } |
| 862 | |
| 863 | if (pcir->classcode[0] != 0 || pcir->classcode[1] != 0 || |
| 864 | pcir->classcode[2] != 3) { |
| 865 | printerr("Not a VGA Option Rom\n"); |
| 866 | return 0; |
| 867 | } |
no test coverage detected