From aff6918b178f4e3d32dfa9bef2adc4dbac318252 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Tue, 27 Sep 2011 15:11:52 +0400 Subject: [PATCH] kernel: Fixups on segment loading in Elf handling Signed-off-by: Cyrill Gorcunov --- ...infmt-elf-for-cr-4 => binfmt-elf-for-cr-5} | 52 ++++++++++--------- 1 file changed, 27 insertions(+), 25 deletions(-) rename kernel/{binfmt-elf-for-cr-4 => binfmt-elf-for-cr-5} (94%) diff --git a/kernel/binfmt-elf-for-cr-4 b/kernel/binfmt-elf-for-cr-5 similarity index 94% rename from kernel/binfmt-elf-for-cr-4 rename to kernel/binfmt-elf-for-cr-5 index 610f0f2b3..b2aa9794f 100644 --- a/kernel/binfmt-elf-for-cr-4 +++ b/kernel/binfmt-elf-for-cr-5 @@ -9,13 +9,18 @@ Elf file format, which includes PT_CKPT_CORE -- 'core_entry' structure and PT_CKPT_PAGES -- 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 +Signed-off-by: Andrew Vagin --- arch/x86/include/asm/elf.h | 3 arch/x86/vdso/vma.c | 22 ++ - fs/binfmt_elf.c | 405 ++++++++++++++++++++++++++++++++++++++++++++- + fs/binfmt_elf.c | 402 ++++++++++++++++++++++++++++++++++++++++++++- 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 =================================================================== @@ -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/fs/binfmt_elf.c -@@ -36,6 +36,11 @@ +@@ -35,6 +35,14 @@ + #include #include #include - ++#include ++#include ++ ++ +#include +#include +#include +#include -+ + static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); static int load_elf_library(struct file *); - static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *, -@@ -556,6 +561,396 @@ static unsigned long randomize_stack_top +@@ -556,6 +564,390 @@ static unsigned long randomize_stack_top #endif } @@ -109,7 +117,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c + int i, ret = -ENOEXEC; + loff_t off; + -+ int cpu, seg; ++ int cpu; + + BUILD_BUG_ON(CKPT_GDT_ENTRY_TLS_ENTRIES != GDT_ENTRY_TLS_ENTRIES); + BUILD_BUG_ON(CKPT_PAGE_SIZE != PAGE_SIZE); @@ -430,23 +438,17 @@ Index: linux-2.6.git/fs/binfmt_elf.c + thread->tls_array[i].b = core_entry.tls_array[i].b; + } + -+ load_TLS(thread, cpu); -+ -+ seg = thread->fsindex; -+ loadsegment(fs, seg); -+ 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) { ++ ret = do_arch_prctl(current, ARCH_SET_FS, core_entry.gpregs.fs_base); ++ if (ret) ++ goto out_unmap; + } + -+ if (core_entry.gpregs.fs_base) -+ wrmsrl(MSR_FS_BASE, core_entry.gpregs.fs_base); -+ -+ load_gs_index(thread->gsindex); -+ if (core_entry.gpregs.gs_base) -+ wrmsrl(MSR_GS_BASE, core_entry.gpregs.gs_base); ++ if (core_entry.gpregs.gs_base) { ++ ret = do_arch_prctl(current, ARCH_SET_GS, core_entry.gpregs.gs_base); ++ if (ret) ++ goto out_unmap; ++ } + + put_cpu(); + @@ -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) { 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) goto out; @@ -488,7 +490,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c goto out; if (!elf_check_arch(&loc->elf_ex)) 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; }