1*1c8c426fSKevin Wolf/* 2*1c8c426fSKevin Wolf * Copyright (c) 2018 Kevin Wolf <kwolf@redhat.com> 3*1c8c426fSKevin Wolf * 4*1c8c426fSKevin Wolf * Permission is hereby granted, free of charge, to any person obtaining a copy 5*1c8c426fSKevin Wolf * of this software and associated documentation files (the "Software"), to deal 6*1c8c426fSKevin Wolf * in the Software without restriction, including without limitation the rights 7*1c8c426fSKevin Wolf * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8*1c8c426fSKevin Wolf * copies of the Software, and to permit persons to whom the Software is 9*1c8c426fSKevin Wolf * furnished to do so, subject to the following conditions: 10*1c8c426fSKevin Wolf * 11*1c8c426fSKevin Wolf * The above copyright notice and this permission notice shall be included in 12*1c8c426fSKevin Wolf * all copies or substantial portions of the Software. 13*1c8c426fSKevin Wolf * 14*1c8c426fSKevin Wolf * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15*1c8c426fSKevin Wolf * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16*1c8c426fSKevin Wolf * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17*1c8c426fSKevin Wolf * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18*1c8c426fSKevin Wolf * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19*1c8c426fSKevin Wolf * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20*1c8c426fSKevin Wolf * THE SOFTWARE. 21*1c8c426fSKevin Wolf */ 22*1c8c426fSKevin Wolf 23*1c8c426fSKevin Wolf.section multiboot 24*1c8c426fSKevin Wolf 25*1c8c426fSKevin Wolf#define MB_MAGIC 0x1badb002 26*1c8c426fSKevin Wolf#define MB_FLAGS 0x10000 27*1c8c426fSKevin Wolf#define MB_CHECKSUM -(MB_MAGIC + MB_FLAGS) 28*1c8c426fSKevin Wolf 29*1c8c426fSKevin Wolf.align 4 30*1c8c426fSKevin Wolf.int MB_MAGIC 31*1c8c426fSKevin Wolf.int MB_FLAGS 32*1c8c426fSKevin Wolf.int MB_CHECKSUM 33*1c8c426fSKevin Wolf 34*1c8c426fSKevin Wolf#define LAST_BYTE_VALUE 0xa5 35*1c8c426fSKevin Wolf 36*1c8c426fSKevin Wolf/* 37*1c8c426fSKevin Wolf * Order of fields in the a.out kludge header fields: 38*1c8c426fSKevin Wolf * 39*1c8c426fSKevin Wolf * header_addr 40*1c8c426fSKevin Wolf * load_addr 41*1c8c426fSKevin Wolf * load_end_addr 42*1c8c426fSKevin Wolf * bss_end_addr 43*1c8c426fSKevin Wolf * entry_addr 44*1c8c426fSKevin Wolf */ 45*1c8c426fSKevin Wolf#if SCENARIO == 1 46*1c8c426fSKevin Wolf/* Well-behaved kernel file with explicit bss_end */ 47*1c8c426fSKevin Wolf.int 0x100000 48*1c8c426fSKevin Wolf.int 0x100000 49*1c8c426fSKevin Wolf.int data_end 50*1c8c426fSKevin Wolf.int data_end 51*1c8c426fSKevin Wolf.int _start 52*1c8c426fSKevin Wolf#elif SCENARIO == 2 53*1c8c426fSKevin Wolf/* Well-behaved kernel file with default bss_end */ 54*1c8c426fSKevin Wolf.int 0x100000 55*1c8c426fSKevin Wolf.int 0x100000 56*1c8c426fSKevin Wolf.int data_end 57*1c8c426fSKevin Wolf.int 0 58*1c8c426fSKevin Wolf.int _start 59*1c8c426fSKevin Wolf#elif SCENARIO == 3 60*1c8c426fSKevin Wolf/* Well-behaved kernel file with default load_end */ 61*1c8c426fSKevin Wolf.int 0x100000 62*1c8c426fSKevin Wolf.int 0x100000 63*1c8c426fSKevin Wolf.int 0 64*1c8c426fSKevin Wolf.int 0 65*1c8c426fSKevin Wolf.int _start 66*1c8c426fSKevin Wolf#elif SCENARIO == 4 67*1c8c426fSKevin Wolf/* Well-behaved kernel file with load_end < data_end and bss > data_end */ 68*1c8c426fSKevin Wolf#undef LAST_BYTE_VALUE 69*1c8c426fSKevin Wolf#define LAST_BYTE_VALUE 0 70*1c8c426fSKevin Wolf.int 0x100000 71*1c8c426fSKevin Wolf.int 0x100000 72*1c8c426fSKevin Wolf.int code_end 73*1c8c426fSKevin Wolf.int 0x140000 74*1c8c426fSKevin Wolf.int _start 75*1c8c426fSKevin Wolf#elif SCENARIO == 5 76*1c8c426fSKevin Wolf/* header < load */ 77*1c8c426fSKevin Wolf.int 0x10000 78*1c8c426fSKevin Wolf.int 0x100000 79*1c8c426fSKevin Wolf.int data_end 80*1c8c426fSKevin Wolf.int data_end 81*1c8c426fSKevin Wolf.int _start 82*1c8c426fSKevin Wolf#elif SCENARIO == 6 83*1c8c426fSKevin Wolf/* load_end < load */ 84*1c8c426fSKevin Wolf.int 0x100000 85*1c8c426fSKevin Wolf.int 0x100000 86*1c8c426fSKevin Wolf.int 0x10000 87*1c8c426fSKevin Wolf.int data_end 88*1c8c426fSKevin Wolf.int _start 89*1c8c426fSKevin Wolf#elif SCENARIO == 7 90*1c8c426fSKevin Wolf/* header much larger than in reality with default load_end */ 91*1c8c426fSKevin Wolf.int 0x80000000 92*1c8c426fSKevin Wolf.int 0x100000 93*1c8c426fSKevin Wolf.int 0 94*1c8c426fSKevin Wolf.int data_end 95*1c8c426fSKevin Wolf.int _start 96*1c8c426fSKevin Wolf#elif SCENARIO == 8 97*1c8c426fSKevin Wolf/* bss_end < load_end - load (regression test for CVE-2018-7550) */ 98*1c8c426fSKevin Wolf.int 0x100000 99*1c8c426fSKevin Wolf.int 0x100000 100*1c8c426fSKevin Wolf.int data_end 101*1c8c426fSKevin Wolf.int code_end 102*1c8c426fSKevin Wolf.int _start 103*1c8c426fSKevin Wolf#elif SCENARIO == 9 104*1c8c426fSKevin Wolf/* Default load_end_addr, load_addr + kernel_file_size > UINT32_MAX */ 105*1c8c426fSKevin Wolf.int 0xfffff000 106*1c8c426fSKevin Wolf.int 0xfffff000 107*1c8c426fSKevin Wolf.int 0 108*1c8c426fSKevin Wolf.int 0xfffff001 109*1c8c426fSKevin Wolf.int _start 110*1c8c426fSKevin Wolf#else 111*1c8c426fSKevin Wolf#error Invalid SCENARIO 112*1c8c426fSKevin Wolf#endif 113*1c8c426fSKevin Wolf 114*1c8c426fSKevin Wolf.section .text 115*1c8c426fSKevin Wolf.global _start 116*1c8c426fSKevin Wolf_start: 117*1c8c426fSKevin Wolf xor %eax, %eax 118*1c8c426fSKevin Wolf 119*1c8c426fSKevin Wolf cmpb $LAST_BYTE_VALUE, last_byte 120*1c8c426fSKevin Wolf je passed 121*1c8c426fSKevin Wolf or $0x1, %eax 122*1c8c426fSKevin Wolfpassed: 123*1c8c426fSKevin Wolf 124*1c8c426fSKevin Wolf /* Test device exit */ 125*1c8c426fSKevin Wolf outl %eax, $0xf4 126*1c8c426fSKevin Wolf 127*1c8c426fSKevin Wolf cli 128*1c8c426fSKevin Wolf hlt 129*1c8c426fSKevin Wolf jmp . 130*1c8c426fSKevin Wolfcode_end: 131*1c8c426fSKevin Wolf 132*1c8c426fSKevin Wolf#if SCENARIO != 8 133*1c8c426fSKevin Wolf.space 8192 134*1c8c426fSKevin Wolf#endif 135*1c8c426fSKevin Wolf 136*1c8c426fSKevin Wolflast_byte: 137*1c8c426fSKevin Wolf.byte 0xa5 138*1c8c426fSKevin Wolfdata_end: 139