~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/kernel/kexec_elf.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * Load ELF vmlinux file for the kexec_file_load syscall.
  4  *
  5  * Copyright (C) 2004  Adam Litke (agl@us.ibm.com)
  6  * Copyright (C) 2004  IBM Corp.
  7  * Copyright (C) 2005  R Sharada (sharada@in.ibm.com)
  8  * Copyright (C) 2006  Mohan Kumar M (mohan@in.ibm.com)
  9  * Copyright (C) 2016  IBM Corporation
 10  *
 11  * Based on kexec-tools' kexec-elf-exec.c and kexec-elf-ppc64.c.
 12  * Heavily modified for the kernel by
 13  * Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>.
 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  * elf_is_ehdr_sane - check that it is safe to use the ELF header
 61  * @buf_len:    size of the buffer in which the ELF file is loaded.
 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                  * e_phnum is at most 65535 so calculating the size of the
 83                  * program header cannot overflow.
 84                  */
 85                 phdr_size = sizeof(struct elf_phdr) * ehdr->e_phnum;
 86 
 87                 /* Sanity check the program header table location. */
 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                  * e_shnum is at most 65536 so calculating
102                  * the size of the section header cannot overflow.
103                  */
104                 shdr_size = sizeof(struct elf_shdr) * ehdr->e_shnum;
105 
106                 /* Sanity check the section header table location. */
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  * elf_is_phdr_sane - check that it is safe to use the program header
183  * @buf_len:    size of the buffer in which the ELF file is loaded.
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         /* Override the const in proghdrs, we are the ones doing the loading. */
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  * elf_read_phdrs - read the program headers from the buffer
247  *
248  * This function assumes that the program header table was checked for sanity.
249  * Use elf_is_ehdr_sane() if it wasn't.
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          * e_phnum is at most 65535 so calculating the size of the
259          * program header cannot overflow.
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  * elf_read_from_buffer - read ELF file and sets up ELF header and ELF info
283  * @buf:        Buffer to read ELF file from.
284  * @len:        Size of @buf.
285  * @ehdr:       Pointer to existing struct which will be populated.
286  * @elf_info:   Pointer to existing struct which will be populated.
287  *
288  * This function allows reading ELF files with different byte order than
289  * the kernel, byte-swapping the fields as needed.
290  *
291  * Return:
292  * On success returns 0, and the caller should call
293  * kexec_free_elf_info(elf_info) to free the memory allocated for the section
294  * and program headers.
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  * kexec_free_elf_info - free memory allocated by elf_read_from_buffer
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  * kexec_build_elf_info - read ELF executable and check that we can use it
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         /* Big endian vmlinux has type ET_DYN. */
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                  * Kexec does not support loading interpreters.
349                  * In addition this check keeps us from attempting
350                  * to kexec ordinay executables.
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  * kexec_elf_load - load ELF executable image
382  * @lowest_load_addr:   On return, will be the address where the first PT_LOAD
383  *                      section will be loaded in memory.
384  *
385  * Return:
386  * 0 on success, negative value on failure.
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         /* Read in the PT_LOAD segments. */
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 }
431 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php