misc.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * misc.c
  4. *
  5. * This is a collection of several routines used to extract the kernel
  6. * which includes KASLR relocation, decompression, ELF parsing, and
  7. * relocation processing. Additionally included are the screen and serial
  8. * output functions and related debugging support functions.
  9. *
  10. * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
  11. * puts by Nick Holloway 1993, better puts by Martin Mares 1995
  12. * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  13. */
  14. #include "misc.h"
  15. #include "error.h"
  16. #include "pgtable.h"
  17. #include "../string.h"
  18. #include "../voffset.h"
  19. /*
  20. * WARNING!!
  21. * This code is compiled with -fPIC and it is relocated dynamically at
  22. * run time, but no relocation processing is performed. This means that
  23. * it is not safe to place pointers in static structures.
  24. */
  25. /* Macros used by the included decompressor code below. */
  26. #define STATIC static
  27. /*
  28. * Use normal definitions of mem*() from string.c. There are already
  29. * included header files which expect a definition of memset() and by
  30. * the time we define memset macro, it is too late.
  31. */
  32. #undef memcpy
  33. #undef memset
  34. #define memzero(s, n) memset((s), 0, (n))
  35. #define memmove memmove
  36. /* Functions used by the included decompressor code below. */
  37. void *memmove(void *dest, const void *src, size_t n);
  38. /*
  39. * This is set up by the setup-routine at boot-time
  40. */
  41. struct boot_params *boot_params;
  42. memptr free_mem_ptr;
  43. memptr free_mem_end_ptr;
  44. static char *vidmem;
  45. static int vidport;
  46. static int lines, cols;
  47. #ifdef CONFIG_KERNEL_GZIP
  48. #include "../../../../lib/decompress_inflate.c"
  49. #endif
  50. #ifdef CONFIG_KERNEL_BZIP2
  51. #include "../../../../lib/decompress_bunzip2.c"
  52. #endif
  53. #ifdef CONFIG_KERNEL_LZMA
  54. #include "../../../../lib/decompress_unlzma.c"
  55. #endif
  56. #ifdef CONFIG_KERNEL_XZ
  57. #include "../../../../lib/decompress_unxz.c"
  58. #endif
  59. #ifdef CONFIG_KERNEL_LZO
  60. #include "../../../../lib/decompress_unlzo.c"
  61. #endif
  62. #ifdef CONFIG_KERNEL_LZ4
  63. #include "../../../../lib/decompress_unlz4.c"
  64. #endif
  65. /*
  66. * NOTE: When adding a new decompressor, please update the analysis in
  67. * ../header.S.
  68. */
  69. static void scroll(void)
  70. {
  71. int i;
  72. memmove(vidmem, vidmem + cols * 2, (lines - 1) * cols * 2);
  73. for (i = (lines - 1) * cols * 2; i < lines * cols * 2; i += 2)
  74. vidmem[i] = ' ';
  75. }
  76. #define XMTRDY 0x20
  77. #define TXR 0 /* Transmit register (WRITE) */
  78. #define LSR 5 /* Line Status */
  79. static void serial_putchar(int ch)
  80. {
  81. unsigned timeout = 0xffff;
  82. while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout)
  83. cpu_relax();
  84. outb(ch, early_serial_base + TXR);
  85. }
  86. void __putstr(const char *s)
  87. {
  88. int x, y, pos;
  89. char c;
  90. if (early_serial_base) {
  91. const char *str = s;
  92. while (*str) {
  93. if (*str == '\n')
  94. serial_putchar('\r');
  95. serial_putchar(*str++);
  96. }
  97. }
  98. if (lines == 0 || cols == 0)
  99. return;
  100. x = boot_params->screen_info.orig_x;
  101. y = boot_params->screen_info.orig_y;
  102. while ((c = *s++) != '\0') {
  103. if (c == '\n') {
  104. x = 0;
  105. if (++y >= lines) {
  106. scroll();
  107. y--;
  108. }
  109. } else {
  110. vidmem[(x + cols * y) * 2] = c;
  111. if (++x >= cols) {
  112. x = 0;
  113. if (++y >= lines) {
  114. scroll();
  115. y--;
  116. }
  117. }
  118. }
  119. }
  120. boot_params->screen_info.orig_x = x;
  121. boot_params->screen_info.orig_y = y;
  122. pos = (x + cols * y) * 2; /* Update cursor position */
  123. outb(14, vidport);
  124. outb(0xff & (pos >> 9), vidport+1);
  125. outb(15, vidport);
  126. outb(0xff & (pos >> 1), vidport+1);
  127. }
  128. void __puthex(unsigned long value)
  129. {
  130. char alpha[2] = "0";
  131. int bits;
  132. for (bits = sizeof(value) * 8 - 4; bits >= 0; bits -= 4) {
  133. unsigned long digit = (value >> bits) & 0xf;
  134. if (digit < 0xA)
  135. alpha[0] = '0' + digit;
  136. else
  137. alpha[0] = 'a' + (digit - 0xA);
  138. __putstr(alpha);
  139. }
  140. }
  141. #if CONFIG_X86_NEED_RELOCS
  142. static void handle_relocations(void *output, unsigned long output_len,
  143. unsigned long virt_addr)
  144. {
  145. int *reloc;
  146. unsigned long delta, map, ptr;
  147. unsigned long min_addr = (unsigned long)output;
  148. unsigned long max_addr = min_addr + (VO___bss_start - VO__text);
  149. /*
  150. * Calculate the delta between where vmlinux was linked to load
  151. * and where it was actually loaded.
  152. */
  153. delta = min_addr - LOAD_PHYSICAL_ADDR;
  154. /*
  155. * The kernel contains a table of relocation addresses. Those
  156. * addresses have the final load address of the kernel in virtual
  157. * memory. We are currently working in the self map. So we need to
  158. * create an adjustment for kernel memory addresses to the self map.
  159. * This will involve subtracting out the base address of the kernel.
  160. */
  161. map = delta - __START_KERNEL_map;
  162. /*
  163. * 32-bit always performs relocations. 64-bit relocations are only
  164. * needed if KASLR has chosen a different starting address offset
  165. * from __START_KERNEL_map.
  166. */
  167. if (IS_ENABLED(CONFIG_X86_64))
  168. delta = virt_addr - LOAD_PHYSICAL_ADDR;
  169. if (!delta) {
  170. debug_putstr("No relocation needed... ");
  171. return;
  172. }
  173. debug_putstr("Performing relocations... ");
  174. /*
  175. * Process relocations: 32 bit relocations first then 64 bit after.
  176. * Three sets of binary relocations are added to the end of the kernel
  177. * before compression. Each relocation table entry is the kernel
  178. * address of the location which needs to be updated stored as a
  179. * 32-bit value which is sign extended to 64 bits.
  180. *
  181. * Format is:
  182. *
  183. * kernel bits...
  184. * 0 - zero terminator for 64 bit relocations
  185. * 64 bit relocation repeated
  186. * 0 - zero terminator for inverse 32 bit relocations
  187. * 32 bit inverse relocation repeated
  188. * 0 - zero terminator for 32 bit relocations
  189. * 32 bit relocation repeated
  190. *
  191. * So we work backwards from the end of the decompressed image.
  192. */
  193. for (reloc = output + output_len - sizeof(*reloc); *reloc; reloc--) {
  194. long extended = *reloc;
  195. extended += map;
  196. ptr = (unsigned long)extended;
  197. if (ptr < min_addr || ptr > max_addr)
  198. error("32-bit relocation outside of kernel!\n");
  199. *(uint32_t *)ptr += delta;
  200. }
  201. #ifdef CONFIG_X86_64
  202. while (*--reloc) {
  203. long extended = *reloc;
  204. extended += map;
  205. ptr = (unsigned long)extended;
  206. if (ptr < min_addr || ptr > max_addr)
  207. error("inverse 32-bit relocation outside of kernel!\n");
  208. *(int32_t *)ptr -= delta;
  209. }
  210. for (reloc--; *reloc; reloc--) {
  211. long extended = *reloc;
  212. extended += map;
  213. ptr = (unsigned long)extended;
  214. if (ptr < min_addr || ptr > max_addr)
  215. error("64-bit relocation outside of kernel!\n");
  216. *(uint64_t *)ptr += delta;
  217. }
  218. #endif
  219. }
  220. #else
  221. static inline void handle_relocations(void *output, unsigned long output_len,
  222. unsigned long virt_addr)
  223. { }
  224. #endif
  225. static void parse_elf(void *output)
  226. {
  227. #ifdef CONFIG_X86_64
  228. Elf64_Ehdr ehdr;
  229. Elf64_Phdr *phdrs, *phdr;
  230. #else
  231. Elf32_Ehdr ehdr;
  232. Elf32_Phdr *phdrs, *phdr;
  233. #endif
  234. void *dest;
  235. int i;
  236. memcpy(&ehdr, output, sizeof(ehdr));
  237. if (ehdr.e_ident[EI_MAG0] != ELFMAG0 ||
  238. ehdr.e_ident[EI_MAG1] != ELFMAG1 ||
  239. ehdr.e_ident[EI_MAG2] != ELFMAG2 ||
  240. ehdr.e_ident[EI_MAG3] != ELFMAG3) {
  241. error("Kernel is not a valid ELF file");
  242. return;
  243. }
  244. debug_putstr("Parsing ELF... ");
  245. phdrs = malloc(sizeof(*phdrs) * ehdr.e_phnum);
  246. if (!phdrs)
  247. error("Failed to allocate space for phdrs");
  248. memcpy(phdrs, output + ehdr.e_phoff, sizeof(*phdrs) * ehdr.e_phnum);
  249. for (i = 0; i < ehdr.e_phnum; i++) {
  250. phdr = &phdrs[i];
  251. switch (phdr->p_type) {
  252. case PT_LOAD:
  253. #ifdef CONFIG_X86_64
  254. if ((phdr->p_align % 0x200000) != 0)
  255. error("Alignment of LOAD segment isn't multiple of 2MB");
  256. #endif
  257. #ifdef CONFIG_RELOCATABLE
  258. dest = output;
  259. dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
  260. #else
  261. dest = (void *)(phdr->p_paddr);
  262. #endif
  263. memmove(dest, output + phdr->p_offset, phdr->p_filesz);
  264. break;
  265. default: /* Ignore other PT_* */ break;
  266. }
  267. }
  268. free(phdrs);
  269. }
  270. /*
  271. * The compressed kernel image (ZO), has been moved so that its position
  272. * is against the end of the buffer used to hold the uncompressed kernel
  273. * image (VO) and the execution environment (.bss, .brk), which makes sure
  274. * there is room to do the in-place decompression. (See header.S for the
  275. * calculations.)
  276. *
  277. * |-----compressed kernel image------|
  278. * V V
  279. * 0 extract_offset +INIT_SIZE
  280. * |-----------|---------------|-------------------------|--------|
  281. * | | | |
  282. * VO__text startup_32 of ZO VO__end ZO__end
  283. * ^ ^
  284. * |-------uncompressed kernel image---------|
  285. *
  286. */
  287. asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
  288. unsigned char *input_data,
  289. unsigned long input_len,
  290. unsigned char *output,
  291. unsigned long output_len)
  292. {
  293. const unsigned long kernel_total_size = VO__end - VO__text;
  294. unsigned long virt_addr = LOAD_PHYSICAL_ADDR;
  295. /* Retain x86 boot parameters pointer passed from startup_32/64. */
  296. boot_params = rmode;
  297. /* Clear flags intended for solely in-kernel use. */
  298. boot_params->hdr.loadflags &= ~KASLR_FLAG;
  299. sanitize_boot_params(boot_params);
  300. if (boot_params->screen_info.orig_video_mode == 7) {
  301. vidmem = (char *) 0xb0000;
  302. vidport = 0x3b4;
  303. } else {
  304. vidmem = (char *) 0xb8000;
  305. vidport = 0x3d4;
  306. }
  307. lines = boot_params->screen_info.orig_video_lines;
  308. cols = boot_params->screen_info.orig_video_cols;
  309. console_init();
  310. debug_putstr("early console in extract_kernel\n");
  311. free_mem_ptr = heap; /* Heap */
  312. free_mem_end_ptr = heap + BOOT_HEAP_SIZE;
  313. /* Report initial kernel position details. */
  314. debug_putaddr(input_data);
  315. debug_putaddr(input_len);
  316. debug_putaddr(output);
  317. debug_putaddr(output_len);
  318. debug_putaddr(kernel_total_size);
  319. #ifdef CONFIG_X86_64
  320. /* Report address of 32-bit trampoline */
  321. debug_putaddr(trampoline_32bit);
  322. #endif
  323. /*
  324. * The memory hole needed for the kernel is the larger of either
  325. * the entire decompressed kernel plus relocation table, or the
  326. * entire decompressed kernel plus .bss and .brk sections.
  327. */
  328. choose_random_location((unsigned long)input_data, input_len,
  329. (unsigned long *)&output,
  330. max(output_len, kernel_total_size),
  331. &virt_addr);
  332. /* Validate memory location choices. */
  333. if ((unsigned long)output & (MIN_KERNEL_ALIGN - 1))
  334. error("Destination physical address inappropriately aligned");
  335. if (virt_addr & (MIN_KERNEL_ALIGN - 1))
  336. error("Destination virtual address inappropriately aligned");
  337. #ifdef CONFIG_X86_64
  338. if (heap > 0x3fffffffffffUL)
  339. error("Destination address too large");
  340. if (virt_addr + max(output_len, kernel_total_size) > KERNEL_IMAGE_SIZE)
  341. error("Destination virtual address is beyond the kernel mapping area");
  342. #else
  343. if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff))
  344. error("Destination address too large");
  345. #endif
  346. #ifndef CONFIG_RELOCATABLE
  347. if ((unsigned long)output != LOAD_PHYSICAL_ADDR)
  348. error("Destination address does not match LOAD_PHYSICAL_ADDR");
  349. if (virt_addr != LOAD_PHYSICAL_ADDR)
  350. error("Destination virtual address changed when not relocatable");
  351. #endif
  352. debug_putstr("\nDecompressing Linux... ");
  353. __decompress(input_data, input_len, NULL, NULL, output, output_len,
  354. NULL, error);
  355. parse_elf(output);
  356. handle_relocations(output, output_len, virt_addr);
  357. debug_putstr("done.\nBooting the kernel.\n");
  358. return output;
  359. }
  360. void fortify_panic(const char *name)
  361. {
  362. error("detected buffer overflow");
  363. }