Commit 2457ce6f authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Andrei Vagin

restore: add arch_prctl mapping compatible vDSO

Map here instead of park before unmap.
TODO: need to check that mapped size is smaller than x86_64 vDSO.

Cc: Cyrill Gorcunov <gorcunov@openvz.org>
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 64d39a20
......@@ -2957,6 +2957,7 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
if (core->tc->has_seccomp_mode)
task_args->seccomp_mode = core->tc->seccomp_mode;
task_args->compatible_mode = core_is_compat(core);
/*
* Arguments for task restoration.
*/
......
......@@ -80,12 +80,14 @@ static inline bool is_vdso_mark(void *addr)
}
extern int vdso_do_park(struct vdso_symtable *sym_rt, unsigned long park_at, unsigned long park_size);
int vdso_map_compat(unsigned long map_at);
extern int vdso_proxify(char *who, struct vdso_symtable *sym_rt,
unsigned long vdso_rt_parked_at, size_t index,
VmaEntry *vmas, size_t nr_vmas);
#else /* CONFIG_VDSO */
#define vdso_do_park(sym_rt, park_at, park_size) (0)
#define vdso_map_compat(map_at) (0)
#endif /* CONFIG_VDSO */
......
......@@ -174,6 +174,8 @@ struct task_restore_args {
int seccomp_mode;
bool compatible_mode;
#ifdef CONFIG_VDSO
unsigned long vdso_rt_size;
struct vdso_symtable vdso_sym_rt; /* runtime vdso symbols */
......
......@@ -68,6 +68,26 @@ int vdso_do_park(struct vdso_symtable *sym_rt, unsigned long park_at, unsigned l
return ret;
}
#ifdef CONFIG_X86_64
#ifndef ARCH_MAP_VDSO_32
# define ARCH_MAP_VDSO_32 0x2002
#endif
int vdso_map_compat(unsigned long map_at)
{
int ret;
pr_debug("Mapping compatible vDSO at %lx\n", map_at);
ret = sys_arch_prctl(ARCH_MAP_VDSO_32, map_at);
return ret;
}
#else
int vdso_map_compat(unsigned long map_at)
{
return 0;
}
#endif
int vdso_proxify(char *who, struct vdso_symtable *sym_rt,
unsigned long vdso_rt_parked_at, size_t index,
VmaEntry *vmas, size_t nr_vmas)
......
......@@ -1087,13 +1087,23 @@ long __export_restore_task(struct task_restore_args *args)
pr_info("Switched to the restorer %d\n", my_pid);
if (vdso_do_park(&args->vdso_sym_rt, args->vdso_rt_parked_at, vdso_rt_size))
goto core_restore_end;
if (!args->compatible_mode) {
/* Compatible vDSO will be mapped, not moved */
if (vdso_do_park(&args->vdso_sym_rt,
args->vdso_rt_parked_at, vdso_rt_size))
goto core_restore_end;
}
if (unmap_old_vmas((void *)args->premmapped_addr, args->premmapped_len,
bootstrap_start, bootstrap_len, args->task_size))
goto core_restore_end;
if (args->compatible_mode) {
/* Map compatible vdso */
if (vdso_map_compat(args->vdso_rt_parked_at))
goto core_restore_end;
}
/* Shift private vma-s to the left */
for (i = 0; i < args->vmas_n; i++) {
vma_entry = args->vmas + i;
......
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