Commit aff6918b authored by Cyrill Gorcunov's avatar Cyrill Gorcunov

kernel: Fixups on segment loading in Elf handling

Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@gmail.com>
parent b1739c08
...@@ -9,13 +9,18 @@ Elf file format, which includes ...@@ -9,13 +9,18 @@ Elf file format, which includes
PT_CKPT_CORE -- 'core_entry' structure and PT_CKPT_PAGES -- PT_CKPT_CORE -- 'core_entry' structure and PT_CKPT_PAGES --
a set of all pages which are to be read into process memory. a set of all pages which are to be read into process memory.
v2: (from Andrew Vagin)
- load fs_base and gs_base via do_arch_prctl
- don't load tls and segments, it will be done in __switch_to
Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Andrew Vagin <avagin@openvz.org>
--- ---
arch/x86/include/asm/elf.h | 3 arch/x86/include/asm/elf.h | 3
arch/x86/vdso/vma.c | 22 ++ arch/x86/vdso/vma.c | 22 ++
fs/binfmt_elf.c | 405 ++++++++++++++++++++++++++++++++++++++++++++- fs/binfmt_elf.c | 402 ++++++++++++++++++++++++++++++++++++++++++++-
include/linux/elf_ckpt.h | 135 +++++++++++++++ include/linux/elf_ckpt.h | 135 +++++++++++++++
4 files changed, 563 insertions(+), 2 deletions(-) 4 files changed, 560 insertions(+), 2 deletions(-)
Index: linux-2.6.git/arch/x86/include/asm/elf.h Index: linux-2.6.git/arch/x86/include/asm/elf.h
=================================================================== ===================================================================
...@@ -68,19 +73,22 @@ Index: linux-2.6.git/fs/binfmt_elf.c ...@@ -68,19 +73,22 @@ Index: linux-2.6.git/fs/binfmt_elf.c
=================================================================== ===================================================================
--- linux-2.6.git.orig/fs/binfmt_elf.c --- linux-2.6.git.orig/fs/binfmt_elf.c
+++ linux-2.6.git/fs/binfmt_elf.c +++ linux-2.6.git/fs/binfmt_elf.c
@@ -36,6 +36,11 @@ @@ -35,6 +35,14 @@
#include <asm/uaccess.h>
#include <asm/param.h> #include <asm/param.h>
#include <asm/page.h> #include <asm/page.h>
+#include <asm/prctl.h>
+#include <asm/proto.h>
+
+
+#include <linux/elf_ckpt.h> +#include <linux/elf_ckpt.h>
+#include <linux/flex_array.h> +#include <linux/flex_array.h>
+#include <asm/tlbflush.h> +#include <asm/tlbflush.h>
+#include <asm/desc.h> +#include <asm/desc.h>
+
static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
static int load_elf_library(struct file *); static int load_elf_library(struct file *);
static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *, @@ -556,6 +564,390 @@ static unsigned long randomize_stack_top
@@ -556,6 +561,396 @@ static unsigned long randomize_stack_top
#endif #endif
} }
...@@ -109,7 +117,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c ...@@ -109,7 +117,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c
+ int i, ret = -ENOEXEC; + int i, ret = -ENOEXEC;
+ loff_t off; + loff_t off;
+ +
+ int cpu, seg; + int cpu;
+ +
+ BUILD_BUG_ON(CKPT_GDT_ENTRY_TLS_ENTRIES != GDT_ENTRY_TLS_ENTRIES); + BUILD_BUG_ON(CKPT_GDT_ENTRY_TLS_ENTRIES != GDT_ENTRY_TLS_ENTRIES);
+ BUILD_BUG_ON(CKPT_PAGE_SIZE != PAGE_SIZE); + BUILD_BUG_ON(CKPT_PAGE_SIZE != PAGE_SIZE);
...@@ -430,23 +438,17 @@ Index: linux-2.6.git/fs/binfmt_elf.c ...@@ -430,23 +438,17 @@ Index: linux-2.6.git/fs/binfmt_elf.c
+ thread->tls_array[i].b = core_entry.tls_array[i].b; + thread->tls_array[i].b = core_entry.tls_array[i].b;
+ } + }
+ +
+ load_TLS(thread, cpu); + if (core_entry.gpregs.fs_base) {
+ + ret = do_arch_prctl(current, ARCH_SET_FS, core_entry.gpregs.fs_base);
+ seg = thread->fsindex; + if (ret)
+ loadsegment(fs, seg); + goto out_unmap;
+ savesegment(fs, seg);
+
+ if (seg != thread->fsindex) {
+ pr_err("Fixup on FS loading exception: %i %i\n",
+ thread->fsindex, seg);
+ } + }
+ +
+ if (core_entry.gpregs.fs_base) + if (core_entry.gpregs.gs_base) {
+ wrmsrl(MSR_FS_BASE, core_entry.gpregs.fs_base); + ret = do_arch_prctl(current, ARCH_SET_GS, core_entry.gpregs.gs_base);
+ + if (ret)
+ load_gs_index(thread->gsindex); + goto out_unmap;
+ if (core_entry.gpregs.gs_base) + }
+ wrmsrl(MSR_GS_BASE, core_entry.gpregs.gs_base);
+ +
+ put_cpu(); + put_cpu();
+ +
...@@ -477,7 +479,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c ...@@ -477,7 +479,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c
static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
{ {
struct file *interpreter = NULL; /* to shut gcc up */ struct file *interpreter = NULL; /* to shut gcc up */
@@ -592,7 +987,9 @@ static int load_elf_binary(struct linux_ @@ -592,7 +984,9 @@ static int load_elf_binary(struct linux_
if (memcmp(loc->elf_ex.e_ident, ELFMAG, SELFMAG) != 0) if (memcmp(loc->elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
goto out; goto out;
...@@ -488,7 +490,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c ...@@ -488,7 +490,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c
goto out; goto out;
if (!elf_check_arch(&loc->elf_ex)) if (!elf_check_arch(&loc->elf_ex))
goto out; goto out;
@@ -619,6 +1016,12 @@ static int load_elf_binary(struct linux_ @@ -619,6 +1013,12 @@ static int load_elf_binary(struct linux_
goto out_free_ph; goto out_free_ph;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment