Commit 001b9033 authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Andrei Vagin

vdso: fill compat symtab in CRIU

The next patch will remove filling in restorer rt symtable
for compat tasks.

travis-ci: success for Rectify 32-bit compatible C/R on x86
Signed-off-by: 's avatarDmitry Safonov <dsafonov@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 598aceb6
...@@ -84,6 +84,8 @@ obj-y += fdstore.o ...@@ -84,6 +84,8 @@ obj-y += fdstore.o
ifeq ($(VDSO),y) ifeq ($(VDSO),y)
obj-y += pie-util-vdso.o obj-y += pie-util-vdso.o
obj-y += vdso.o obj-y += vdso.o
obj-y += pie-util-vdso-elf32.o
CFLAGS_pie-util-vdso-elf32.o += -DCONFIG_VDSO_32
endif endif
PROTOBUF_GEN := $(SRC_DIR)/scripts/protobuf-gen.sh PROTOBUF_GEN := $(SRC_DIR)/scripts/protobuf-gen.sh
......
...@@ -93,5 +93,12 @@ static inline unsigned long vvar_vma_size(struct vdso_symtable *t) ...@@ -93,5 +93,12 @@ static inline unsigned long vvar_vma_size(struct vdso_symtable *t)
#endif #endif
extern int vdso_fill_symtable(uintptr_t mem, size_t size, struct vdso_symtable *t); extern int vdso_fill_symtable(uintptr_t mem, size_t size, struct vdso_symtable *t);
#if defined(CONFIG_X86_64) && defined(CONFIG_COMPAT)
#ifndef ARCH_MAP_VDSO_32
# define ARCH_MAP_VDSO_32 0x2002
#endif
extern int vdso_fill_symtable_compat(uintptr_t mem, size_t size,
struct vdso_symtable *t);
#endif
#endif /* __CR_UTIL_VDSO_H__ */ #endif /* __CR_UTIL_VDSO_H__ */
pie/util-vdso-elf32.c
\ No newline at end of file
...@@ -69,12 +69,6 @@ int vdso_do_park(struct vdso_symtable *sym_rt, unsigned long park_at, unsigned l ...@@ -69,12 +69,6 @@ int vdso_do_park(struct vdso_symtable *sym_rt, unsigned long park_at, unsigned l
} }
#if defined(CONFIG_X86_64) && defined(CONFIG_COMPAT) #if defined(CONFIG_X86_64) && defined(CONFIG_COMPAT)
#ifndef ARCH_MAP_VDSO_32
# define ARCH_MAP_VDSO_32 0x2002
#endif
extern int vdso_fill_symtable_compat(uintptr_t mem, size_t size,
struct vdso_symtable *t);
int vdso_map_compat(unsigned long map_at, unsigned long *park_size, int vdso_map_compat(unsigned long map_at, unsigned long *park_size,
struct vdso_symtable *sym_rt) struct vdso_symtable *sym_rt)
{ {
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/wait.h>
#include "types.h" #include "types.h"
#include "parasite-syscall.h" #include "parasite-syscall.h"
...@@ -20,6 +21,7 @@ ...@@ -20,6 +21,7 @@
#include "mem.h" #include "mem.h"
#include "vma.h" #include "vma.h"
#include <compel/compel.h> #include <compel/compel.h>
#include <compel/plugins/std/syscall.h>
#ifdef LOG_PREFIX #ifdef LOG_PREFIX
# undef LOG_PREFIX # undef LOG_PREFIX
...@@ -28,6 +30,7 @@ ...@@ -28,6 +30,7 @@
struct vdso_symtable vdso_sym_rt = VDSO_SYMTABLE_INIT; struct vdso_symtable vdso_sym_rt = VDSO_SYMTABLE_INIT;
u64 vdso_pfn = VDSO_BAD_PFN; u64 vdso_pfn = VDSO_BAD_PFN;
struct vdso_symtable vdso_compat_rt = VDSO_SYMTABLE_INIT;
/* /*
* The VMAs list might have proxy vdso/vvar areas left * The VMAs list might have proxy vdso/vvar areas left
* from previous dump/restore cycle so we need to detect * from previous dump/restore cycle so we need to detect
...@@ -325,10 +328,73 @@ static int vdso_fill_self_symtable(struct vdso_symtable *s) ...@@ -325,10 +328,73 @@ static int vdso_fill_self_symtable(struct vdso_symtable *s)
return 0; return 0;
} }
static int vdso_fill_compat_symtable(struct vdso_symtable *native,
struct vdso_symtable *compat)
{
#ifdef CONFIG_COMPAT
pid_t pid;
int status, ret = -1;
pid = fork();
if (pid == 0) {
size_t vma_size = native->vma_end - native->vma_start;
if (syscall(__NR_munmap, native->vma_start, vma_size))
syscall(__NR_exit, 1);
vma_size = native->vvar_end - native->vvar_start;
if (syscall(__NR_munmap, native->vvar_start, vma_size))
syscall(__NR_exit, 2);
if (syscall(__NR_arch_prctl, ARCH_MAP_VDSO_32, native->vma_start) < 0)
syscall(__NR_exit, 3);
syscall(__NR_kill, syscall(__NR_getpid), SIGSTOP);
/* this helper should be killed at this point */
BUG();
}
waitpid(pid, &status, WUNTRACED);
if (WIFEXITED(status)) {
pr_err("Compat vdso helper exited with %d\n",
WEXITSTATUS(status));
goto out_kill;
}
if (!WIFSTOPPED(status)) {
pr_err("Compat vdso helper isn't stopped\n");
goto out_kill;
}
if (vdso_parse_maps(pid, compat))
goto out_kill;
if (vdso_fill_symtable_compat(compat->vma_start,
compat->vma_end - compat->vma_start, compat))
goto out_kill;
if (validate_vdso_addr(compat))
goto out_kill;
pr_debug("compat [vdso] %lx-%lx [vvar] %lx-%lx\n",
compat->vma_start, compat->vma_end,
compat->vvar_start, compat->vvar_end);
ret = 0;
out_kill:
kill(pid, SIGKILL);
return ret;
#else
return 0;
#endif
}
int vdso_init(void) int vdso_init(void)
{ {
if (vdso_fill_self_symtable(&vdso_sym_rt)) if (vdso_fill_self_symtable(&vdso_sym_rt))
return -1; return -1;
if (vdso_fill_compat_symtable(&vdso_sym_rt, &vdso_compat_rt))
return -1;
if (kdat.pmap != PM_FULL) if (kdat.pmap != PM_FULL)
pr_info("VDSO detection turned off\n"); pr_info("VDSO detection turned off\n");
......
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