1 /* $OpenBSD: exec_elf.c,v 1.18 2021/10/24 21:24:18 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
30 #include <elf.h>
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
adjust(caddr_t x)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
readjust(caddr_t x)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
loadkernel(char * file)96 loadkernel(char *file)
97 {
98 int fd;
99
100 if ((fd = open(file, O_RDONLY | O_EXLOCK)) == -1)
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
savekernel(char * outfile)139 savekernel(char *outfile)
140 {
141 int fd;
142
143 if ((fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0700)) == -1)
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 }
151