|
13 | 13 | #include <linux/module.h>
|
14 | 14 | #include <linux/kernel.h>
|
15 | 15 | #include <linux/fs.h>
|
| 16 | +#include <linux/log2.h> |
16 | 17 | #include <linux/mm.h>
|
17 | 18 | #include <linux/mman.h>
|
18 | 19 | #include <linux/errno.h>
|
@@ -421,6 +422,26 @@ static int elf_read(struct file *file, void *buf, size_t len, loff_t pos)
|
421 | 422 | return 0;
|
422 | 423 | }
|
423 | 424 |
|
| 425 | +static unsigned long maximum_alignment(struct elf_phdr *cmds, int nr) |
| 426 | +{ |
| 427 | + unsigned long alignment = 0; |
| 428 | + int i; |
| 429 | + |
| 430 | + for (i = 0; i < nr; i++) { |
| 431 | + if (cmds[i].p_type == PT_LOAD) { |
| 432 | + unsigned long p_align = cmds[i].p_align; |
| 433 | + |
| 434 | + /* skip non-power of two alignments as invalid */ |
| 435 | + if (!is_power_of_2(p_align)) |
| 436 | + continue; |
| 437 | + alignment = max(alignment, p_align); |
| 438 | + } |
| 439 | + } |
| 440 | + |
| 441 | + /* ensure we align to at least one page */ |
| 442 | + return ELF_PAGEALIGN(alignment); |
| 443 | +} |
| 444 | + |
424 | 445 | /**
|
425 | 446 | * load_elf_phdrs() - load ELF program headers
|
426 | 447 | * @elf_ex: ELF header of the binary whose program headers should be loaded
|
@@ -1008,6 +1029,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
|
1008 | 1029 | int elf_prot, elf_flags;
|
1009 | 1030 | unsigned long k, vaddr;
|
1010 | 1031 | unsigned long total_size = 0;
|
| 1032 | + unsigned long alignment; |
1011 | 1033 |
|
1012 | 1034 | if (elf_ppnt->p_type != PT_LOAD)
|
1013 | 1035 | continue;
|
@@ -1086,6 +1108,9 @@ static int load_elf_binary(struct linux_binprm *bprm)
|
1086 | 1108 | load_bias = ELF_ET_DYN_BASE;
|
1087 | 1109 | if (current->flags & PF_RANDOMIZE)
|
1088 | 1110 | load_bias += arch_mmap_rnd();
|
| 1111 | + alignment = maximum_alignment(elf_phdata, elf_ex->e_phnum); |
| 1112 | + if (alignment) |
| 1113 | + load_bias &= ~(alignment - 1); |
1089 | 1114 | elf_flags |= MAP_FIXED;
|
1090 | 1115 | } else
|
1091 | 1116 | load_bias = 0;
|
|
0 commit comments