]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.19.7/fs-binfmt_elf.c-fix-bug-in-loading-of-pie-binaries.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.19.7 / fs-binfmt_elf.c-fix-bug-in-loading-of-pie-binaries.patch
1 From a87938b2e246b81b4fb713edb371a9fa3c5c3c86 Mon Sep 17 00:00:00 2001
2 From: Michael Davidson <md@google.com>
3 Date: Tue, 14 Apr 2015 15:47:38 -0700
4 Subject: fs/binfmt_elf.c: fix bug in loading of PIE binaries
5
6 From: Michael Davidson <md@google.com>
7
8 commit a87938b2e246b81b4fb713edb371a9fa3c5c3c86 upstream.
9
10 With CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE enabled, and a normal top-down
11 address allocation strategy, load_elf_binary() will attempt to map a PIE
12 binary into an address range immediately below mm->mmap_base.
13
14 Unfortunately, load_elf_ binary() does not take account of the need to
15 allocate sufficient space for the entire binary which means that, while
16 the first PT_LOAD segment is mapped below mm->mmap_base, the subsequent
17 PT_LOAD segment(s) end up being mapped above mm->mmap_base into the are
18 that is supposed to be the "gap" between the stack and the binary.
19
20 Since the size of the "gap" on x86_64 is only guaranteed to be 128MB this
21 means that binaries with large data segments > 128MB can end up mapping
22 part of their data segment over their stack resulting in corruption of the
23 stack (and the data segment once the binary starts to run).
24
25 Any PIE binary with a data segment > 128MB is vulnerable to this although
26 address randomization means that the actual gap between the stack and the
27 end of the binary is normally greater than 128MB. The larger the data
28 segment of the binary the higher the probability of failure.
29
30 Fix this by calculating the total size of the binary in the same way as
31 load_elf_interp().
32
33 Signed-off-by: Michael Davidson <md@google.com>
34 Cc: Alexander Viro <viro@zeniv.linux.org.uk>
35 Cc: Jiri Kosina <jkosina@suse.cz>
36 Cc: Kees Cook <keescook@chromium.org>
37 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
38 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
39 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
40
41 ---
42 fs/binfmt_elf.c | 9 ++++++++-
43 1 file changed, 8 insertions(+), 1 deletion(-)
44
45 --- a/fs/binfmt_elf.c
46 +++ b/fs/binfmt_elf.c
47 @@ -862,6 +862,7 @@ static int load_elf_binary(struct linux_
48 i < loc->elf_ex.e_phnum; i++, elf_ppnt++) {
49 int elf_prot = 0, elf_flags;
50 unsigned long k, vaddr;
51 + unsigned long total_size = 0;
52
53 if (elf_ppnt->p_type != PT_LOAD)
54 continue;
55 @@ -924,10 +925,16 @@ static int load_elf_binary(struct linux_
56 #else
57 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
58 #endif
59 + total_size = total_mapping_size(elf_phdata,
60 + loc->elf_ex.e_phnum);
61 + if (!total_size) {
62 + error = -EINVAL;
63 + goto out_free_dentry;
64 + }
65 }
66
67 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
68 - elf_prot, elf_flags, 0);
69 + elf_prot, elf_flags, total_size);
70 if (BAD_ADDR(error)) {
71 retval = IS_ERR((void *)error) ?
72 PTR_ERR((void*)error) : -EINVAL;