1175fca3bSSven Schnelle // SPDX-License-Identifier: GPL-2.0-only
2175fca3bSSven Schnelle /*
3175fca3bSSven Schnelle * Load ELF vmlinux file for the kexec_file_load syscall.
4175fca3bSSven Schnelle *
5175fca3bSSven Schnelle * Copyright (C) 2004 Adam Litke (agl@us.ibm.com)
6175fca3bSSven Schnelle * Copyright (C) 2004 IBM Corp.
7175fca3bSSven Schnelle * Copyright (C) 2005 R Sharada (sharada@in.ibm.com)
8175fca3bSSven Schnelle * Copyright (C) 2006 Mohan Kumar M (mohan@in.ibm.com)
9175fca3bSSven Schnelle * Copyright (C) 2016 IBM Corporation
10175fca3bSSven Schnelle *
11175fca3bSSven Schnelle * Based on kexec-tools' kexec-elf-exec.c and kexec-elf-ppc64.c.
12175fca3bSSven Schnelle * Heavily modified for the kernel by
13175fca3bSSven Schnelle * Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>.
14175fca3bSSven Schnelle */
15175fca3bSSven Schnelle
16175fca3bSSven Schnelle #define pr_fmt(fmt) "kexec_elf: " fmt
17175fca3bSSven Schnelle
18175fca3bSSven Schnelle #include <linux/elf.h>
19175fca3bSSven Schnelle #include <linux/kexec.h>
20175fca3bSSven Schnelle #include <linux/module.h>
21175fca3bSSven Schnelle #include <linux/slab.h>
22175fca3bSSven Schnelle #include <linux/types.h>
23175fca3bSSven Schnelle
elf_is_elf_file(const struct elfhdr * ehdr)24175fca3bSSven Schnelle static inline bool elf_is_elf_file(const struct elfhdr *ehdr)
25175fca3bSSven Schnelle {
26175fca3bSSven Schnelle return memcmp(ehdr->e_ident, ELFMAG, SELFMAG) == 0;
27175fca3bSSven Schnelle }
28175fca3bSSven Schnelle
elf64_to_cpu(const struct elfhdr * ehdr,uint64_t value)29175fca3bSSven Schnelle static uint64_t elf64_to_cpu(const struct elfhdr *ehdr, uint64_t value)
30175fca3bSSven Schnelle {
31175fca3bSSven Schnelle if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
32175fca3bSSven Schnelle value = le64_to_cpu(value);
33175fca3bSSven Schnelle else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
34175fca3bSSven Schnelle value = be64_to_cpu(value);
35175fca3bSSven Schnelle
36175fca3bSSven Schnelle return value;
37175fca3bSSven Schnelle }
38175fca3bSSven Schnelle
elf32_to_cpu(const struct elfhdr * ehdr,uint32_t value)39175fca3bSSven Schnelle static uint32_t elf32_to_cpu(const struct elfhdr *ehdr, uint32_t value)
40175fca3bSSven Schnelle {
41175fca3bSSven Schnelle if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
42175fca3bSSven Schnelle value = le32_to_cpu(value);
43175fca3bSSven Schnelle else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
44175fca3bSSven Schnelle value = be32_to_cpu(value);
45175fca3bSSven Schnelle
46175fca3bSSven Schnelle return value;
47175fca3bSSven Schnelle }
48175fca3bSSven Schnelle
elf16_to_cpu(const struct elfhdr * ehdr,uint16_t value)49d34e0ad3SSven Schnelle static uint16_t elf16_to_cpu(const struct elfhdr *ehdr, uint16_t value)
50d34e0ad3SSven Schnelle {
51d34e0ad3SSven Schnelle if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
52d34e0ad3SSven Schnelle value = le16_to_cpu(value);
53d34e0ad3SSven Schnelle else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
54d34e0ad3SSven Schnelle value = be16_to_cpu(value);
55d34e0ad3SSven Schnelle
56d34e0ad3SSven Schnelle return value;
57d34e0ad3SSven Schnelle }
58d34e0ad3SSven Schnelle
59175fca3bSSven Schnelle /**
60175fca3bSSven Schnelle * elf_is_ehdr_sane - check that it is safe to use the ELF header
61175fca3bSSven Schnelle * @buf_len: size of the buffer in which the ELF file is loaded.
62175fca3bSSven Schnelle */
elf_is_ehdr_sane(const struct elfhdr * ehdr,size_t buf_len)63175fca3bSSven Schnelle static bool elf_is_ehdr_sane(const struct elfhdr *ehdr, size_t buf_len)
64175fca3bSSven Schnelle {
65175fca3bSSven Schnelle if (ehdr->e_phnum > 0 && ehdr->e_phentsize != sizeof(struct elf_phdr)) {
66175fca3bSSven Schnelle pr_debug("Bad program header size.\n");
67175fca3bSSven Schnelle return false;
68175fca3bSSven Schnelle } else if (ehdr->e_shnum > 0 &&
69175fca3bSSven Schnelle ehdr->e_shentsize != sizeof(struct elf_shdr)) {
70175fca3bSSven Schnelle pr_debug("Bad section header size.\n");
71175fca3bSSven Schnelle return false;
72175fca3bSSven Schnelle } else if (ehdr->e_ident[EI_VERSION] != EV_CURRENT ||
73175fca3bSSven Schnelle ehdr->e_version != EV_CURRENT) {
74175fca3bSSven Schnelle pr_debug("Unknown ELF version.\n");
75175fca3bSSven Schnelle return false;
76175fca3bSSven Schnelle }
77175fca3bSSven Schnelle
78175fca3bSSven Schnelle if (ehdr->e_phoff > 0 && ehdr->e_phnum > 0) {
79175fca3bSSven Schnelle size_t phdr_size;
80175fca3bSSven Schnelle
81175fca3bSSven Schnelle /*
82175fca3bSSven Schnelle * e_phnum is at most 65535 so calculating the size of the
83175fca3bSSven Schnelle * program header cannot overflow.
84175fca3bSSven Schnelle */
85175fca3bSSven Schnelle phdr_size = sizeof(struct elf_phdr) * ehdr->e_phnum;
86175fca3bSSven Schnelle
87175fca3bSSven Schnelle /* Sanity check the program header table location. */
88175fca3bSSven Schnelle if (ehdr->e_phoff + phdr_size < ehdr->e_phoff) {
89175fca3bSSven Schnelle pr_debug("Program headers at invalid location.\n");
90175fca3bSSven Schnelle return false;
91175fca3bSSven Schnelle } else if (ehdr->e_phoff + phdr_size > buf_len) {
92175fca3bSSven Schnelle pr_debug("Program headers truncated.\n");
93175fca3bSSven Schnelle return false;
94175fca3bSSven Schnelle }
95175fca3bSSven Schnelle }
96175fca3bSSven Schnelle
97175fca3bSSven Schnelle if (ehdr->e_shoff > 0 && ehdr->e_shnum > 0) {
98175fca3bSSven Schnelle size_t shdr_size;
99175fca3bSSven Schnelle
100175fca3bSSven Schnelle /*
101175fca3bSSven Schnelle * e_shnum is at most 65536 so calculating
102175fca3bSSven Schnelle * the size of the section header cannot overflow.
103175fca3bSSven Schnelle */
104175fca3bSSven Schnelle shdr_size = sizeof(struct elf_shdr) * ehdr->e_shnum;
105175fca3bSSven Schnelle
106175fca3bSSven Schnelle /* Sanity check the section header table location. */
107175fca3bSSven Schnelle if (ehdr->e_shoff + shdr_size < ehdr->e_shoff) {
108175fca3bSSven Schnelle pr_debug("Section headers at invalid location.\n");
109175fca3bSSven Schnelle return false;
110175fca3bSSven Schnelle } else if (ehdr->e_shoff + shdr_size > buf_len) {
111175fca3bSSven Schnelle pr_debug("Section headers truncated.\n");
112175fca3bSSven Schnelle return false;
113175fca3bSSven Schnelle }
114175fca3bSSven Schnelle }
115175fca3bSSven Schnelle
116175fca3bSSven Schnelle return true;
117175fca3bSSven Schnelle }
118175fca3bSSven Schnelle
elf_read_ehdr(const char * buf,size_t len,struct elfhdr * ehdr)119175fca3bSSven Schnelle static int elf_read_ehdr(const char *buf, size_t len, struct elfhdr *ehdr)
120175fca3bSSven Schnelle {
121175fca3bSSven Schnelle struct elfhdr *buf_ehdr;
122175fca3bSSven Schnelle
123175fca3bSSven Schnelle if (len < sizeof(*buf_ehdr)) {
124175fca3bSSven Schnelle pr_debug("Buffer is too small to hold ELF header.\n");
125175fca3bSSven Schnelle return -ENOEXEC;
126175fca3bSSven Schnelle }
127175fca3bSSven Schnelle
128175fca3bSSven Schnelle memset(ehdr, 0, sizeof(*ehdr));
129175fca3bSSven Schnelle memcpy(ehdr->e_ident, buf, sizeof(ehdr->e_ident));
130175fca3bSSven Schnelle if (!elf_is_elf_file(ehdr)) {
131175fca3bSSven Schnelle pr_debug("No ELF header magic.\n");
132175fca3bSSven Schnelle return -ENOEXEC;
133175fca3bSSven Schnelle }
134175fca3bSSven Schnelle
135175fca3bSSven Schnelle if (ehdr->e_ident[EI_CLASS] != ELF_CLASS) {
136175fca3bSSven Schnelle pr_debug("Not a supported ELF class.\n");
137175fca3bSSven Schnelle return -ENOEXEC;
138175fca3bSSven Schnelle } else if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB &&
139175fca3bSSven Schnelle ehdr->e_ident[EI_DATA] != ELFDATA2MSB) {
140175fca3bSSven Schnelle pr_debug("Not a supported ELF data format.\n");
141175fca3bSSven Schnelle return -ENOEXEC;
142175fca3bSSven Schnelle }
143175fca3bSSven Schnelle
144175fca3bSSven Schnelle buf_ehdr = (struct elfhdr *) buf;
145175fca3bSSven Schnelle if (elf16_to_cpu(ehdr, buf_ehdr->e_ehsize) != sizeof(*buf_ehdr)) {
146175fca3bSSven Schnelle pr_debug("Bad ELF header size.\n");
147175fca3bSSven Schnelle return -ENOEXEC;
148175fca3bSSven Schnelle }
149175fca3bSSven Schnelle
150175fca3bSSven Schnelle ehdr->e_type = elf16_to_cpu(ehdr, buf_ehdr->e_type);
151175fca3bSSven Schnelle ehdr->e_machine = elf16_to_cpu(ehdr, buf_ehdr->e_machine);
152175fca3bSSven Schnelle ehdr->e_version = elf32_to_cpu(ehdr, buf_ehdr->e_version);
153175fca3bSSven Schnelle ehdr->e_flags = elf32_to_cpu(ehdr, buf_ehdr->e_flags);
154175fca3bSSven Schnelle ehdr->e_phentsize = elf16_to_cpu(ehdr, buf_ehdr->e_phentsize);
155175fca3bSSven Schnelle ehdr->e_phnum = elf16_to_cpu(ehdr, buf_ehdr->e_phnum);
156175fca3bSSven Schnelle ehdr->e_shentsize = elf16_to_cpu(ehdr, buf_ehdr->e_shentsize);
157175fca3bSSven Schnelle ehdr->e_shnum = elf16_to_cpu(ehdr, buf_ehdr->e_shnum);
158175fca3bSSven Schnelle ehdr->e_shstrndx = elf16_to_cpu(ehdr, buf_ehdr->e_shstrndx);
159175fca3bSSven Schnelle
160*ea46a13eSSven Schnelle switch (ehdr->e_ident[EI_CLASS]) {
161*ea46a13eSSven Schnelle case ELFCLASS64:
162*ea46a13eSSven Schnelle ehdr->e_entry = elf64_to_cpu(ehdr, buf_ehdr->e_entry);
163*ea46a13eSSven Schnelle ehdr->e_phoff = elf64_to_cpu(ehdr, buf_ehdr->e_phoff);
164*ea46a13eSSven Schnelle ehdr->e_shoff = elf64_to_cpu(ehdr, buf_ehdr->e_shoff);
165*ea46a13eSSven Schnelle break;
166*ea46a13eSSven Schnelle
167*ea46a13eSSven Schnelle case ELFCLASS32:
168*ea46a13eSSven Schnelle ehdr->e_entry = elf32_to_cpu(ehdr, buf_ehdr->e_entry);
169*ea46a13eSSven Schnelle ehdr->e_phoff = elf32_to_cpu(ehdr, buf_ehdr->e_phoff);
170*ea46a13eSSven Schnelle ehdr->e_shoff = elf32_to_cpu(ehdr, buf_ehdr->e_shoff);
171*ea46a13eSSven Schnelle break;
172*ea46a13eSSven Schnelle
173*ea46a13eSSven Schnelle default:
174*ea46a13eSSven Schnelle pr_debug("Unknown ELF class.\n");
175*ea46a13eSSven Schnelle return -EINVAL;
176*ea46a13eSSven Schnelle }
177*ea46a13eSSven Schnelle
178175fca3bSSven Schnelle return elf_is_ehdr_sane(ehdr, len) ? 0 : -ENOEXEC;
179175fca3bSSven Schnelle }
180175fca3bSSven Schnelle
181175fca3bSSven Schnelle /**
182175fca3bSSven Schnelle * elf_is_phdr_sane - check that it is safe to use the program header
183175fca3bSSven Schnelle * @buf_len: size of the buffer in which the ELF file is loaded.
184175fca3bSSven Schnelle */
elf_is_phdr_sane(const struct elf_phdr * phdr,size_t buf_len)185175fca3bSSven Schnelle static bool elf_is_phdr_sane(const struct elf_phdr *phdr, size_t buf_len)
186175fca3bSSven Schnelle {
187175fca3bSSven Schnelle
188175fca3bSSven Schnelle if (phdr->p_offset + phdr->p_filesz < phdr->p_offset) {
189175fca3bSSven Schnelle pr_debug("ELF segment location wraps around.\n");
190175fca3bSSven Schnelle return false;
191175fca3bSSven Schnelle } else if (phdr->p_offset + phdr->p_filesz > buf_len) {
192175fca3bSSven Schnelle pr_debug("ELF segment not in file.\n");
193175fca3bSSven Schnelle return false;
194175fca3bSSven Schnelle } else if (phdr->p_paddr + phdr->p_memsz < phdr->p_paddr) {
195175fca3bSSven Schnelle pr_debug("ELF segment address wraps around.\n");
196175fca3bSSven Schnelle return false;
197175fca3bSSven Schnelle }
198175fca3bSSven Schnelle
199175fca3bSSven Schnelle return true;
200175fca3bSSven Schnelle }
201175fca3bSSven Schnelle
elf_read_phdr(const char * buf,size_t len,struct kexec_elf_info * elf_info,int idx)202175fca3bSSven Schnelle static int elf_read_phdr(const char *buf, size_t len,
203175fca3bSSven Schnelle struct kexec_elf_info *elf_info,
204175fca3bSSven Schnelle int idx)
205175fca3bSSven Schnelle {
206175fca3bSSven Schnelle /* Override the const in proghdrs, we are the ones doing the loading. */
207175fca3bSSven Schnelle struct elf_phdr *phdr = (struct elf_phdr *) &elf_info->proghdrs[idx];
208*ea46a13eSSven Schnelle const struct elfhdr *ehdr = elf_info->ehdr;
209175fca3bSSven Schnelle const char *pbuf;
210175fca3bSSven Schnelle struct elf_phdr *buf_phdr;
211175fca3bSSven Schnelle
212175fca3bSSven Schnelle pbuf = buf + elf_info->ehdr->e_phoff + (idx * sizeof(*buf_phdr));
213175fca3bSSven Schnelle buf_phdr = (struct elf_phdr *) pbuf;
214175fca3bSSven Schnelle
215175fca3bSSven Schnelle phdr->p_type = elf32_to_cpu(elf_info->ehdr, buf_phdr->p_type);
216175fca3bSSven Schnelle phdr->p_flags = elf32_to_cpu(elf_info->ehdr, buf_phdr->p_flags);
217175fca3bSSven Schnelle
218*ea46a13eSSven Schnelle switch (ehdr->e_ident[EI_CLASS]) {
219*ea46a13eSSven Schnelle case ELFCLASS64:
220*ea46a13eSSven Schnelle phdr->p_offset = elf64_to_cpu(ehdr, buf_phdr->p_offset);
221*ea46a13eSSven Schnelle phdr->p_paddr = elf64_to_cpu(ehdr, buf_phdr->p_paddr);
222*ea46a13eSSven Schnelle phdr->p_vaddr = elf64_to_cpu(ehdr, buf_phdr->p_vaddr);
223*ea46a13eSSven Schnelle phdr->p_filesz = elf64_to_cpu(ehdr, buf_phdr->p_filesz);
224*ea46a13eSSven Schnelle phdr->p_memsz = elf64_to_cpu(ehdr, buf_phdr->p_memsz);
225*ea46a13eSSven Schnelle phdr->p_align = elf64_to_cpu(ehdr, buf_phdr->p_align);
226*ea46a13eSSven Schnelle break;
227*ea46a13eSSven Schnelle
228*ea46a13eSSven Schnelle case ELFCLASS32:
229*ea46a13eSSven Schnelle phdr->p_offset = elf32_to_cpu(ehdr, buf_phdr->p_offset);
230*ea46a13eSSven Schnelle phdr->p_paddr = elf32_to_cpu(ehdr, buf_phdr->p_paddr);
231*ea46a13eSSven Schnelle phdr->p_vaddr = elf32_to_cpu(ehdr, buf_phdr->p_vaddr);
232*ea46a13eSSven Schnelle phdr->p_filesz = elf32_to_cpu(ehdr, buf_phdr->p_filesz);
233*ea46a13eSSven Schnelle phdr->p_memsz = elf32_to_cpu(ehdr, buf_phdr->p_memsz);
234*ea46a13eSSven Schnelle phdr->p_align = elf32_to_cpu(ehdr, buf_phdr->p_align);
235*ea46a13eSSven Schnelle break;
236*ea46a13eSSven Schnelle
237*ea46a13eSSven Schnelle default:
238*ea46a13eSSven Schnelle pr_debug("Unknown ELF class.\n");
239*ea46a13eSSven Schnelle return -EINVAL;
240*ea46a13eSSven Schnelle }
241175fca3bSSven Schnelle
242175fca3bSSven Schnelle return elf_is_phdr_sane(phdr, len) ? 0 : -ENOEXEC;
243175fca3bSSven Schnelle }
244175fca3bSSven Schnelle
245175fca3bSSven Schnelle /**
246175fca3bSSven Schnelle * elf_read_phdrs - read the program headers from the buffer
247175fca3bSSven Schnelle *
248175fca3bSSven Schnelle * This function assumes that the program header table was checked for sanity.
249175fca3bSSven Schnelle * Use elf_is_ehdr_sane() if it wasn't.
250175fca3bSSven Schnelle */
elf_read_phdrs(const char * buf,size_t len,struct kexec_elf_info * elf_info)251175fca3bSSven Schnelle static int elf_read_phdrs(const char *buf, size_t len,
252175fca3bSSven Schnelle struct kexec_elf_info *elf_info)
253175fca3bSSven Schnelle {
254175fca3bSSven Schnelle size_t phdr_size, i;
255175fca3bSSven Schnelle const struct elfhdr *ehdr = elf_info->ehdr;
256175fca3bSSven Schnelle
257175fca3bSSven Schnelle /*
258175fca3bSSven Schnelle * e_phnum is at most 65535 so calculating the size of the
259175fca3bSSven Schnelle * program header cannot overflow.
260175fca3bSSven Schnelle */
261175fca3bSSven Schnelle phdr_size = sizeof(struct elf_phdr) * ehdr->e_phnum;
262175fca3bSSven Schnelle
263175fca3bSSven Schnelle elf_info->proghdrs = kzalloc(phdr_size, GFP_KERNEL);
264175fca3bSSven Schnelle if (!elf_info->proghdrs)
265175fca3bSSven Schnelle return -ENOMEM;
266175fca3bSSven Schnelle
267175fca3bSSven Schnelle for (i = 0; i < ehdr->e_phnum; i++) {
268175fca3bSSven Schnelle int ret;
269175fca3bSSven Schnelle
270175fca3bSSven Schnelle ret = elf_read_phdr(buf, len, elf_info, i);
271175fca3bSSven Schnelle if (ret) {
272175fca3bSSven Schnelle kfree(elf_info->proghdrs);
273175fca3bSSven Schnelle elf_info->proghdrs = NULL;
274175fca3bSSven Schnelle return ret;
275175fca3bSSven Schnelle }
276175fca3bSSven Schnelle }
277175fca3bSSven Schnelle
278175fca3bSSven Schnelle return 0;
279175fca3bSSven Schnelle }
280175fca3bSSven Schnelle
281175fca3bSSven Schnelle /**
282175fca3bSSven Schnelle * elf_read_from_buffer - read ELF file and sets up ELF header and ELF info
283175fca3bSSven Schnelle * @buf: Buffer to read ELF file from.
284175fca3bSSven Schnelle * @len: Size of @buf.
285175fca3bSSven Schnelle * @ehdr: Pointer to existing struct which will be populated.
286175fca3bSSven Schnelle * @elf_info: Pointer to existing struct which will be populated.
287175fca3bSSven Schnelle *
288175fca3bSSven Schnelle * This function allows reading ELF files with different byte order than
289175fca3bSSven Schnelle * the kernel, byte-swapping the fields as needed.
290175fca3bSSven Schnelle *
291175fca3bSSven Schnelle * Return:
292175fca3bSSven Schnelle * On success returns 0, and the caller should call
293175fca3bSSven Schnelle * kexec_free_elf_info(elf_info) to free the memory allocated for the section
294175fca3bSSven Schnelle * and program headers.
295175fca3bSSven Schnelle */
elf_read_from_buffer(const char * buf,size_t len,struct elfhdr * ehdr,struct kexec_elf_info * elf_info)296175fca3bSSven Schnelle static int elf_read_from_buffer(const char *buf, size_t len,
297175fca3bSSven Schnelle struct elfhdr *ehdr,
298175fca3bSSven Schnelle struct kexec_elf_info *elf_info)
299175fca3bSSven Schnelle {
300175fca3bSSven Schnelle int ret;
301175fca3bSSven Schnelle
302175fca3bSSven Schnelle ret = elf_read_ehdr(buf, len, ehdr);
303175fca3bSSven Schnelle if (ret)
304175fca3bSSven Schnelle return ret;
305175fca3bSSven Schnelle
306175fca3bSSven Schnelle elf_info->buffer = buf;
307175fca3bSSven Schnelle elf_info->ehdr = ehdr;
308175fca3bSSven Schnelle if (ehdr->e_phoff > 0 && ehdr->e_phnum > 0) {
309175fca3bSSven Schnelle ret = elf_read_phdrs(buf, len, elf_info);
310175fca3bSSven Schnelle if (ret)
311175fca3bSSven Schnelle return ret;
312175fca3bSSven Schnelle }
313175fca3bSSven Schnelle return 0;
314175fca3bSSven Schnelle }
315175fca3bSSven Schnelle
316175fca3bSSven Schnelle /**
317175fca3bSSven Schnelle * kexec_free_elf_info - free memory allocated by elf_read_from_buffer
318175fca3bSSven Schnelle */
kexec_free_elf_info(struct kexec_elf_info * elf_info)319175fca3bSSven Schnelle void kexec_free_elf_info(struct kexec_elf_info *elf_info)
320175fca3bSSven Schnelle {
321175fca3bSSven Schnelle kfree(elf_info->proghdrs);
322175fca3bSSven Schnelle memset(elf_info, 0, sizeof(*elf_info));
323175fca3bSSven Schnelle }
324175fca3bSSven Schnelle /**
325175fca3bSSven Schnelle * kexec_build_elf_info - read ELF executable and check that we can use it
326175fca3bSSven Schnelle */
kexec_build_elf_info(const char * buf,size_t len,struct elfhdr * ehdr,struct kexec_elf_info * elf_info)327175fca3bSSven Schnelle int kexec_build_elf_info(const char *buf, size_t len, struct elfhdr *ehdr,
328175fca3bSSven Schnelle struct kexec_elf_info *elf_info)
329175fca3bSSven Schnelle {
330175fca3bSSven Schnelle int i;
331175fca3bSSven Schnelle int ret;
332175fca3bSSven Schnelle
333175fca3bSSven Schnelle ret = elf_read_from_buffer(buf, len, ehdr, elf_info);
334175fca3bSSven Schnelle if (ret)
335175fca3bSSven Schnelle return ret;
336175fca3bSSven Schnelle
337175fca3bSSven Schnelle /* Big endian vmlinux has type ET_DYN. */
338175fca3bSSven Schnelle if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) {
339175fca3bSSven Schnelle pr_err("Not an ELF executable.\n");
340175fca3bSSven Schnelle goto error;
341175fca3bSSven Schnelle } else if (!elf_info->proghdrs) {
342175fca3bSSven Schnelle pr_err("No ELF program header.\n");
343175fca3bSSven Schnelle goto error;
344175fca3bSSven Schnelle }
345175fca3bSSven Schnelle
346175fca3bSSven Schnelle for (i = 0; i < ehdr->e_phnum; i++) {
347175fca3bSSven Schnelle /*
348175fca3bSSven Schnelle * Kexec does not support loading interpreters.
349175fca3bSSven Schnelle * In addition this check keeps us from attempting
350175fca3bSSven Schnelle * to kexec ordinay executables.
351175fca3bSSven Schnelle */
352175fca3bSSven Schnelle if (elf_info->proghdrs[i].p_type == PT_INTERP) {
353175fca3bSSven Schnelle pr_err("Requires an ELF interpreter.\n");
354175fca3bSSven Schnelle goto error;
355175fca3bSSven Schnelle }
356175fca3bSSven Schnelle }
357175fca3bSSven Schnelle
358175fca3bSSven Schnelle return 0;
359175fca3bSSven Schnelle error:
360175fca3bSSven Schnelle kexec_free_elf_info(elf_info);
361175fca3bSSven Schnelle return -ENOEXEC;
362175fca3bSSven Schnelle }
363175fca3bSSven Schnelle
364175fca3bSSven Schnelle
kexec_elf_probe(const char * buf,unsigned long len)365175fca3bSSven Schnelle int kexec_elf_probe(const char *buf, unsigned long len)
366175fca3bSSven Schnelle {
367175fca3bSSven Schnelle struct elfhdr ehdr;
368175fca3bSSven Schnelle struct kexec_elf_info elf_info;
369175fca3bSSven Schnelle int ret;
370175fca3bSSven Schnelle
371175fca3bSSven Schnelle ret = kexec_build_elf_info(buf, len, &ehdr, &elf_info);
372175fca3bSSven Schnelle if (ret)
373175fca3bSSven Schnelle return ret;
374175fca3bSSven Schnelle
375175fca3bSSven Schnelle kexec_free_elf_info(&elf_info);
376175fca3bSSven Schnelle
377175fca3bSSven Schnelle return elf_check_arch(&ehdr) ? 0 : -ENOEXEC;
378175fca3bSSven Schnelle }
379175fca3bSSven Schnelle
380175fca3bSSven Schnelle /**
381175fca3bSSven Schnelle * kexec_elf_load - load ELF executable image
382175fca3bSSven Schnelle * @lowest_load_addr: On return, will be the address where the first PT_LOAD
383175fca3bSSven Schnelle * section will be loaded in memory.
384175fca3bSSven Schnelle *
385175fca3bSSven Schnelle * Return:
386175fca3bSSven Schnelle * 0 on success, negative value on failure.
387175fca3bSSven Schnelle */
kexec_elf_load(struct kimage * image,struct elfhdr * ehdr,struct kexec_elf_info * elf_info,struct kexec_buf * kbuf,unsigned long * lowest_load_addr)388175fca3bSSven Schnelle int kexec_elf_load(struct kimage *image, struct elfhdr *ehdr,
389175fca3bSSven Schnelle struct kexec_elf_info *elf_info,
390175fca3bSSven Schnelle struct kexec_buf *kbuf,
391175fca3bSSven Schnelle unsigned long *lowest_load_addr)
392175fca3bSSven Schnelle {
393571ceb7dSSven Schnelle unsigned long lowest_addr = UINT_MAX;
394175fca3bSSven Schnelle int ret;
395175fca3bSSven Schnelle size_t i;
396175fca3bSSven Schnelle
397175fca3bSSven Schnelle /* Read in the PT_LOAD segments. */
398175fca3bSSven Schnelle for (i = 0; i < ehdr->e_phnum; i++) {
399175fca3bSSven Schnelle unsigned long load_addr;
400175fca3bSSven Schnelle size_t size;
401175fca3bSSven Schnelle const struct elf_phdr *phdr;
402175fca3bSSven Schnelle
403175fca3bSSven Schnelle phdr = &elf_info->proghdrs[i];
404175fca3bSSven Schnelle if (phdr->p_type != PT_LOAD)
405175fca3bSSven Schnelle continue;
406175fca3bSSven Schnelle
407175fca3bSSven Schnelle size = phdr->p_filesz;
408175fca3bSSven Schnelle if (size > phdr->p_memsz)
409175fca3bSSven Schnelle size = phdr->p_memsz;
410175fca3bSSven Schnelle
411175fca3bSSven Schnelle kbuf->buffer = (void *) elf_info->buffer + phdr->p_offset;
412175fca3bSSven Schnelle kbuf->bufsz = size;
413175fca3bSSven Schnelle kbuf->memsz = phdr->p_memsz;
414175fca3bSSven Schnelle kbuf->buf_align = phdr->p_align;
415571ceb7dSSven Schnelle kbuf->buf_min = phdr->p_paddr;
416175fca3bSSven Schnelle kbuf->mem = KEXEC_BUF_MEM_UNKNOWN;
417175fca3bSSven Schnelle ret = kexec_add_buffer(kbuf);
418175fca3bSSven Schnelle if (ret)
419175fca3bSSven Schnelle goto out;
420175fca3bSSven Schnelle load_addr = kbuf->mem;
421175fca3bSSven Schnelle
422175fca3bSSven Schnelle if (load_addr < lowest_addr)
423175fca3bSSven Schnelle lowest_addr = load_addr;
424175fca3bSSven Schnelle }
425175fca3bSSven Schnelle
426175fca3bSSven Schnelle *lowest_load_addr = lowest_addr;
427175fca3bSSven Schnelle ret = 0;
428175fca3bSSven Schnelle out:
429175fca3bSSven Schnelle return ret;
430175fca3bSSven Schnelle }
431