1 |
|
|
/* $OpenBSD: exec_elf.c,v 1.15 2017/06/03 23:31:37 deraadt Exp $ */ |
2 |
|
|
|
3 |
|
|
/* |
4 |
|
|
* Copyright (c) 1999 Mats O Jansson. All rights reserved. |
5 |
|
|
* |
6 |
|
|
* Redistribution and use in source and binary forms, with or without |
7 |
|
|
* modification, are permitted provided that the following conditions |
8 |
|
|
* are met: |
9 |
|
|
* 1. Redistributions of source code must retain the above copyright |
10 |
|
|
* notice, this list of conditions and the following disclaimer. |
11 |
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
12 |
|
|
* notice, this list of conditions and the following disclaimer in the |
13 |
|
|
* documentation and/or other materials provided with the distribution. |
14 |
|
|
* |
15 |
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
16 |
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
17 |
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
18 |
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
19 |
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
20 |
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
21 |
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
22 |
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 |
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
24 |
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 |
|
|
*/ |
26 |
|
|
|
27 |
|
|
#include <sys/types.h> |
28 |
|
|
#include <sys/exec.h> |
29 |
|
|
#include <sys/exec_elf.h> |
30 |
|
|
|
31 |
|
|
#include <err.h> |
32 |
|
|
#include <errno.h> |
33 |
|
|
#include <fcntl.h> |
34 |
|
|
#include <nlist.h> |
35 |
|
|
#include <stdio.h> |
36 |
|
|
#include <stdlib.h> |
37 |
|
|
#include <unistd.h> |
38 |
|
|
|
39 |
|
|
#include "ukc.h" |
40 |
|
|
#include "config.h" |
41 |
|
|
#include "exec.h" |
42 |
|
|
|
43 |
|
|
caddr_t ptr, rest, pre; |
44 |
|
|
Elf_Ehdr elf_ex; |
45 |
|
|
Elf_Phdr *elf_phdr; |
46 |
|
|
Elf_Shdr *elf_shdr; |
47 |
|
|
char *elf_total; |
48 |
|
|
char *elf_shstrtab; |
49 |
|
|
off_t elf_size; |
50 |
|
|
|
51 |
|
|
caddr_t |
52 |
|
|
adjust(caddr_t x) |
53 |
|
|
{ |
54 |
|
|
int i; |
55 |
|
|
Elf_Shdr *s; |
56 |
|
|
unsigned long y = 0; |
57 |
|
|
|
58 |
|
|
s = elf_shdr; |
59 |
|
|
|
60 |
|
|
for (i = 0; i < elf_ex.e_shnum; i++) { |
61 |
|
|
if (s[i].sh_addr == 0) |
62 |
|
|
continue; |
63 |
|
|
if (((unsigned long)x >= s[i].sh_addr) && |
64 |
|
|
((unsigned long)x < (s[i].sh_addr+s[i].sh_size))) { |
65 |
|
|
y = (unsigned long)&elf_total[(unsigned long)x - |
66 |
|
|
s[i].sh_addr + s[i].sh_offset]; |
67 |
|
|
break; |
68 |
|
|
} |
69 |
|
|
} |
70 |
|
|
|
71 |
|
|
return((caddr_t)y); |
72 |
|
|
} |
73 |
|
|
|
74 |
|
|
caddr_t |
75 |
|
|
readjust(caddr_t x) |
76 |
|
|
{ |
77 |
|
|
int i; |
78 |
|
|
Elf_Shdr *s; |
79 |
|
|
unsigned long y = 0; |
80 |
|
|
|
81 |
|
|
s = elf_shdr; |
82 |
|
|
|
83 |
|
|
for (i = 0; i < elf_ex.e_shnum; i++) { |
84 |
|
|
if (s[i].sh_addr == 0) |
85 |
|
|
continue; |
86 |
|
|
if (((x - elf_total) >= s[i].sh_offset) && |
87 |
|
|
((x - elf_total) <= (s[i].sh_offset + s[i].sh_size))) |
88 |
|
|
y = (unsigned long)x - (unsigned long)elf_total + |
89 |
|
|
(unsigned long)s[i].sh_addr - s[i].sh_offset; |
90 |
|
|
} |
91 |
|
|
|
92 |
|
|
return((caddr_t)y); |
93 |
|
|
} |
94 |
|
|
|
95 |
|
|
void |
96 |
|
|
loadkernel(char *file) |
97 |
|
|
{ |
98 |
|
|
int fd; |
99 |
|
|
|
100 |
|
|
if ((fd = open(file, O_RDONLY | O_EXLOCK, 0)) < 0) |
101 |
|
|
err(1, "%s", file); |
102 |
|
|
|
103 |
|
|
if (read(fd, (char *)&elf_ex, sizeof(elf_ex)) != sizeof(elf_ex)) |
104 |
|
|
errx(1, "can't read elf header"); |
105 |
|
|
|
106 |
|
|
if (!IS_ELF(elf_ex)) |
107 |
|
|
errx(1, "bad elf magic"); |
108 |
|
|
|
109 |
|
|
elf_size = lseek(fd, (off_t)0, SEEK_END); |
110 |
|
|
(void)lseek(fd, (off_t)0, SEEK_SET); |
111 |
|
|
elf_total = emalloc((size_t)elf_size); |
112 |
|
|
|
113 |
|
|
if (read(fd, elf_total, (size_t)elf_size) != elf_size) |
114 |
|
|
errx(1, "can't read elf kernel"); |
115 |
|
|
|
116 |
|
|
if (elf_ex.e_phoff > (size_t)elf_size) |
117 |
|
|
errx(1, "incorrect ELF header or truncated file"); |
118 |
|
|
if (elf_ex.e_shoff > (size_t)elf_size) |
119 |
|
|
errx(1, "incorrect ELF header or truncated file"); |
120 |
|
|
|
121 |
|
|
elf_phdr = (Elf_Phdr *)&elf_total[elf_ex.e_phoff]; |
122 |
|
|
elf_shdr = (Elf_Shdr *)&elf_total[elf_ex.e_shoff]; |
123 |
|
|
|
124 |
|
|
if ((char *)&elf_shdr[elf_ex.e_shstrndx] + |
125 |
|
|
sizeof(elf_shdr[elf_ex.e_shstrndx]) >= elf_total + (size_t)elf_size) |
126 |
|
|
errx(1, "incorrect ELF header or truncated file"); |
127 |
|
|
|
128 |
|
|
if ((char *)&elf_shdr[elf_ex.e_shstrndx].sh_offset + |
129 |
|
|
sizeof(elf_shdr[elf_ex.e_shstrndx].sh_offset) >= |
130 |
|
|
elf_total + (size_t)elf_size) |
131 |
|
|
errx(1, "incorrect ELF header or truncated file"); |
132 |
|
|
|
133 |
|
|
elf_shstrtab = &elf_total[elf_shdr[elf_ex.e_shstrndx].sh_offset]; |
134 |
|
|
|
135 |
|
|
close(fd); |
136 |
|
|
} |
137 |
|
|
|
138 |
|
|
void |
139 |
|
|
savekernel(char *outfile) |
140 |
|
|
{ |
141 |
|
|
int fd; |
142 |
|
|
|
143 |
|
|
if ((fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0700)) < 0) |
144 |
|
|
err(1, "%s", outfile); |
145 |
|
|
|
146 |
|
|
if (write(fd, elf_total, (size_t)elf_size) != elf_size) |
147 |
|
|
errx(1, "can't write file %s", outfile); |
148 |
|
|
|
149 |
|
|
close(fd); |
150 |
|
|
} |