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 }