xref: /linux/kernel/kexec_elf.c (revision ea46a13e)
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