This source file includes following definitions.
- elf_is_elf_file
- elf64_to_cpu
- elf32_to_cpu
- elf16_to_cpu
- elf_is_ehdr_sane
- elf_read_ehdr
- elf_is_phdr_sane
- elf_read_phdr
- elf_read_phdrs
- elf_read_from_buffer
- kexec_free_elf_info
- kexec_build_elf_info
- kexec_elf_probe
- kexec_elf_load
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #define pr_fmt(fmt) "kexec_elf: " fmt
17
18 #include <linux/elf.h>
19 #include <linux/kexec.h>
20 #include <linux/module.h>
21 #include <linux/slab.h>
22 #include <linux/types.h>
23
24 static inline bool elf_is_elf_file(const struct elfhdr *ehdr)
25 {
26 return memcmp(ehdr->e_ident, ELFMAG, SELFMAG) == 0;
27 }
28
29 static uint64_t elf64_to_cpu(const struct elfhdr *ehdr, uint64_t value)
30 {
31 if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
32 value = le64_to_cpu(value);
33 else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
34 value = be64_to_cpu(value);
35
36 return value;
37 }
38
39 static uint32_t elf32_to_cpu(const struct elfhdr *ehdr, uint32_t value)
40 {
41 if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
42 value = le32_to_cpu(value);
43 else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
44 value = be32_to_cpu(value);
45
46 return value;
47 }
48
49 static uint16_t elf16_to_cpu(const struct elfhdr *ehdr, uint16_t value)
50 {
51 if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
52 value = le16_to_cpu(value);
53 else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
54 value = be16_to_cpu(value);
55
56 return value;
57 }
58
59
60
61
62
63 static bool elf_is_ehdr_sane(const struct elfhdr *ehdr, size_t buf_len)
64 {
65 if (ehdr->e_phnum > 0 && ehdr->e_phentsize != sizeof(struct elf_phdr)) {
66 pr_debug("Bad program header size.\n");
67 return false;
68 } else if (ehdr->e_shnum > 0 &&
69 ehdr->e_shentsize != sizeof(struct elf_shdr)) {
70 pr_debug("Bad section header size.\n");
71 return false;
72 } else if (ehdr->e_ident[EI_VERSION] != EV_CURRENT ||
73 ehdr->e_version != EV_CURRENT) {
74 pr_debug("Unknown ELF version.\n");
75 return false;
76 }
77
78 if (ehdr->e_phoff > 0 && ehdr->e_phnum > 0) {
79 size_t phdr_size;
80
81
82
83
84
85 phdr_size = sizeof(struct elf_phdr) * ehdr->e_phnum;
86
87
88 if (ehdr->e_phoff + phdr_size < ehdr->e_phoff) {
89 pr_debug("Program headers at invalid location.\n");
90 return false;
91 } else if (ehdr->e_phoff + phdr_size > buf_len) {
92 pr_debug("Program headers truncated.\n");
93 return false;
94 }
95 }
96
97 if (ehdr->e_shoff > 0 && ehdr->e_shnum > 0) {
98 size_t shdr_size;
99
100
101
102
103
104 shdr_size = sizeof(struct elf_shdr) * ehdr->e_shnum;
105
106
107 if (ehdr->e_shoff + shdr_size < ehdr->e_shoff) {
108 pr_debug("Section headers at invalid location.\n");
109 return false;
110 } else if (ehdr->e_shoff + shdr_size > buf_len) {
111 pr_debug("Section headers truncated.\n");
112 return false;
113 }
114 }
115
116 return true;
117 }
118
119 static int elf_read_ehdr(const char *buf, size_t len, struct elfhdr *ehdr)
120 {
121 struct elfhdr *buf_ehdr;
122
123 if (len < sizeof(*buf_ehdr)) {
124 pr_debug("Buffer is too small to hold ELF header.\n");
125 return -ENOEXEC;
126 }
127
128 memset(ehdr, 0, sizeof(*ehdr));
129 memcpy(ehdr->e_ident, buf, sizeof(ehdr->e_ident));
130 if (!elf_is_elf_file(ehdr)) {
131 pr_debug("No ELF header magic.\n");
132 return -ENOEXEC;
133 }
134
135 if (ehdr->e_ident[EI_CLASS] != ELF_CLASS) {
136 pr_debug("Not a supported ELF class.\n");
137 return -ENOEXEC;
138 } else if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB &&
139 ehdr->e_ident[EI_DATA] != ELFDATA2MSB) {
140 pr_debug("Not a supported ELF data format.\n");
141 return -ENOEXEC;
142 }
143
144 buf_ehdr = (struct elfhdr *) buf;
145 if (elf16_to_cpu(ehdr, buf_ehdr->e_ehsize) != sizeof(*buf_ehdr)) {
146 pr_debug("Bad ELF header size.\n");
147 return -ENOEXEC;
148 }
149
150 ehdr->e_type = elf16_to_cpu(ehdr, buf_ehdr->e_type);
151 ehdr->e_machine = elf16_to_cpu(ehdr, buf_ehdr->e_machine);
152 ehdr->e_version = elf32_to_cpu(ehdr, buf_ehdr->e_version);
153 ehdr->e_flags = elf32_to_cpu(ehdr, buf_ehdr->e_flags);
154 ehdr->e_phentsize = elf16_to_cpu(ehdr, buf_ehdr->e_phentsize);
155 ehdr->e_phnum = elf16_to_cpu(ehdr, buf_ehdr->e_phnum);
156 ehdr->e_shentsize = elf16_to_cpu(ehdr, buf_ehdr->e_shentsize);
157 ehdr->e_shnum = elf16_to_cpu(ehdr, buf_ehdr->e_shnum);
158 ehdr->e_shstrndx = elf16_to_cpu(ehdr, buf_ehdr->e_shstrndx);
159
160 switch (ehdr->e_ident[EI_CLASS]) {
161 case ELFCLASS64:
162 ehdr->e_entry = elf64_to_cpu(ehdr, buf_ehdr->e_entry);
163 ehdr->e_phoff = elf64_to_cpu(ehdr, buf_ehdr->e_phoff);
164 ehdr->e_shoff = elf64_to_cpu(ehdr, buf_ehdr->e_shoff);
165 break;
166
167 case ELFCLASS32:
168 ehdr->e_entry = elf32_to_cpu(ehdr, buf_ehdr->e_entry);
169 ehdr->e_phoff = elf32_to_cpu(ehdr, buf_ehdr->e_phoff);
170 ehdr->e_shoff = elf32_to_cpu(ehdr, buf_ehdr->e_shoff);
171 break;
172
173 default:
174 pr_debug("Unknown ELF class.\n");
175 return -EINVAL;
176 }
177
178 return elf_is_ehdr_sane(ehdr, len) ? 0 : -ENOEXEC;
179 }
180
181
182
183
184
185 static bool elf_is_phdr_sane(const struct elf_phdr *phdr, size_t buf_len)
186 {
187
188 if (phdr->p_offset + phdr->p_filesz < phdr->p_offset) {
189 pr_debug("ELF segment location wraps around.\n");
190 return false;
191 } else if (phdr->p_offset + phdr->p_filesz > buf_len) {
192 pr_debug("ELF segment not in file.\n");
193 return false;
194 } else if (phdr->p_paddr + phdr->p_memsz < phdr->p_paddr) {
195 pr_debug("ELF segment address wraps around.\n");
196 return false;
197 }
198
199 return true;
200 }
201
202 static int elf_read_phdr(const char *buf, size_t len,
203 struct kexec_elf_info *elf_info,
204 int idx)
205 {
206
207 struct elf_phdr *phdr = (struct elf_phdr *) &elf_info->proghdrs[idx];
208 const struct elfhdr *ehdr = elf_info->ehdr;
209 const char *pbuf;
210 struct elf_phdr *buf_phdr;
211
212 pbuf = buf + elf_info->ehdr->e_phoff + (idx * sizeof(*buf_phdr));
213 buf_phdr = (struct elf_phdr *) pbuf;
214
215 phdr->p_type = elf32_to_cpu(elf_info->ehdr, buf_phdr->p_type);
216 phdr->p_flags = elf32_to_cpu(elf_info->ehdr, buf_phdr->p_flags);
217
218 switch (ehdr->e_ident[EI_CLASS]) {
219 case ELFCLASS64:
220 phdr->p_offset = elf64_to_cpu(ehdr, buf_phdr->p_offset);
221 phdr->p_paddr = elf64_to_cpu(ehdr, buf_phdr->p_paddr);
222 phdr->p_vaddr = elf64_to_cpu(ehdr, buf_phdr->p_vaddr);
223 phdr->p_filesz = elf64_to_cpu(ehdr, buf_phdr->p_filesz);
224 phdr->p_memsz = elf64_to_cpu(ehdr, buf_phdr->p_memsz);
225 phdr->p_align = elf64_to_cpu(ehdr, buf_phdr->p_align);
226 break;
227
228 case ELFCLASS32:
229 phdr->p_offset = elf32_to_cpu(ehdr, buf_phdr->p_offset);
230 phdr->p_paddr = elf32_to_cpu(ehdr, buf_phdr->p_paddr);
231 phdr->p_vaddr = elf32_to_cpu(ehdr, buf_phdr->p_vaddr);
232 phdr->p_filesz = elf32_to_cpu(ehdr, buf_phdr->p_filesz);
233 phdr->p_memsz = elf32_to_cpu(ehdr, buf_phdr->p_memsz);
234 phdr->p_align = elf32_to_cpu(ehdr, buf_phdr->p_align);
235 break;
236
237 default:
238 pr_debug("Unknown ELF class.\n");
239 return -EINVAL;
240 }
241
242 return elf_is_phdr_sane(phdr, len) ? 0 : -ENOEXEC;
243 }
244
245
246
247
248
249
250
251 static int elf_read_phdrs(const char *buf, size_t len,
252 struct kexec_elf_info *elf_info)
253 {
254 size_t phdr_size, i;
255 const struct elfhdr *ehdr = elf_info->ehdr;
256
257
258
259
260
261 phdr_size = sizeof(struct elf_phdr) * ehdr->e_phnum;
262
263 elf_info->proghdrs = kzalloc(phdr_size, GFP_KERNEL);
264 if (!elf_info->proghdrs)
265 return -ENOMEM;
266
267 for (i = 0; i < ehdr->e_phnum; i++) {
268 int ret;
269
270 ret = elf_read_phdr(buf, len, elf_info, i);
271 if (ret) {
272 kfree(elf_info->proghdrs);
273 elf_info->proghdrs = NULL;
274 return ret;
275 }
276 }
277
278 return 0;
279 }
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296 static int elf_read_from_buffer(const char *buf, size_t len,
297 struct elfhdr *ehdr,
298 struct kexec_elf_info *elf_info)
299 {
300 int ret;
301
302 ret = elf_read_ehdr(buf, len, ehdr);
303 if (ret)
304 return ret;
305
306 elf_info->buffer = buf;
307 elf_info->ehdr = ehdr;
308 if (ehdr->e_phoff > 0 && ehdr->e_phnum > 0) {
309 ret = elf_read_phdrs(buf, len, elf_info);
310 if (ret)
311 return ret;
312 }
313 return 0;
314 }
315
316
317
318
319 void kexec_free_elf_info(struct kexec_elf_info *elf_info)
320 {
321 kfree(elf_info->proghdrs);
322 memset(elf_info, 0, sizeof(*elf_info));
323 }
324
325
326
327 int kexec_build_elf_info(const char *buf, size_t len, struct elfhdr *ehdr,
328 struct kexec_elf_info *elf_info)
329 {
330 int i;
331 int ret;
332
333 ret = elf_read_from_buffer(buf, len, ehdr, elf_info);
334 if (ret)
335 return ret;
336
337
338 if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) {
339 pr_err("Not an ELF executable.\n");
340 goto error;
341 } else if (!elf_info->proghdrs) {
342 pr_err("No ELF program header.\n");
343 goto error;
344 }
345
346 for (i = 0; i < ehdr->e_phnum; i++) {
347
348
349
350
351
352 if (elf_info->proghdrs[i].p_type == PT_INTERP) {
353 pr_err("Requires an ELF interpreter.\n");
354 goto error;
355 }
356 }
357
358 return 0;
359 error:
360 kexec_free_elf_info(elf_info);
361 return -ENOEXEC;
362 }
363
364
365 int kexec_elf_probe(const char *buf, unsigned long len)
366 {
367 struct elfhdr ehdr;
368 struct kexec_elf_info elf_info;
369 int ret;
370
371 ret = kexec_build_elf_info(buf, len, &ehdr, &elf_info);
372 if (ret)
373 return ret;
374
375 kexec_free_elf_info(&elf_info);
376
377 return elf_check_arch(&ehdr) ? 0 : -ENOEXEC;
378 }
379
380
381
382
383
384
385
386
387
388 int kexec_elf_load(struct kimage *image, struct elfhdr *ehdr,
389 struct kexec_elf_info *elf_info,
390 struct kexec_buf *kbuf,
391 unsigned long *lowest_load_addr)
392 {
393 unsigned long lowest_addr = UINT_MAX;
394 int ret;
395 size_t i;
396
397
398 for (i = 0; i < ehdr->e_phnum; i++) {
399 unsigned long load_addr;
400 size_t size;
401 const struct elf_phdr *phdr;
402
403 phdr = &elf_info->proghdrs[i];
404 if (phdr->p_type != PT_LOAD)
405 continue;
406
407 size = phdr->p_filesz;
408 if (size > phdr->p_memsz)
409 size = phdr->p_memsz;
410
411 kbuf->buffer = (void *) elf_info->buffer + phdr->p_offset;
412 kbuf->bufsz = size;
413 kbuf->memsz = phdr->p_memsz;
414 kbuf->buf_align = phdr->p_align;
415 kbuf->buf_min = phdr->p_paddr;
416 kbuf->mem = KEXEC_BUF_MEM_UNKNOWN;
417 ret = kexec_add_buffer(kbuf);
418 if (ret)
419 goto out;
420 load_addr = kbuf->mem;
421
422 if (load_addr < lowest_addr)
423 lowest_addr = load_addr;
424 }
425
426 *lowest_load_addr = lowest_addr;
427 ret = 0;
428 out:
429 return ret;
430 }