Commit 3cd00d04 authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Andrei Vagin

compat: check arch_prctl() return code for ARCH_MAP_VDSO_32

On first versions of x86 compat patches it returned 0 or err.
In merged version it returns error < 0 or vDSO blob's size.

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 69070b13
......@@ -80,7 +80,7 @@ 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);
extern int vdso_map_compat(unsigned long map_at, unsigned long park_size,
extern int vdso_map_compat(unsigned long map_at, unsigned long *park_size,
struct vdso_symtable *sym_rt);
extern int vdso_proxify(char *who, struct vdso_symtable *sym_rt,
unsigned long vdso_rt_parked_at, size_t index,
......
......@@ -75,7 +75,7 @@ int vdso_do_park(struct vdso_symtable *sym_rt, unsigned long park_at, unsigned l
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)
{
unsigned long search_vdso;
......@@ -84,18 +84,22 @@ int vdso_map_compat(unsigned long map_at, unsigned long park_size,
pr_debug("Mapping compatible vDSO at %lx\n", map_at);
ret = sys_arch_prctl(ARCH_MAP_VDSO_32, map_at);
if (ret)
if (ret < 0)
return ret;
*park_size = (unsigned long)ret;
/*
* We could map VVAR firstly, or VDSO.
* Try to find VDSO pages in this couple of parking pages.
* XXX: Please, FIXME - compat vdso/vvar sizes should be counted
* at CRIU start time by parsing /proc/<...>/maps then by searching
* ELF magic.
*/
for (search_vdso = map_at; search_vdso < map_at + park_size;
for (search_vdso = map_at; search_vdso < map_at + *park_size;
search_vdso += PAGE_SIZE)
{
ret = vdso_fill_symtable_compat(search_vdso,
map_at + park_size - search_vdso, sym_rt);
map_at + *park_size - search_vdso, sym_rt);
if (!ret)
return 0;
}
......@@ -113,9 +117,11 @@ int __vdso_fill_symtable(uintptr_t mem, size_t size,
}
#else
int vdso_map_compat(unsigned long __always_unused map_at,
unsigned long __always_unused park_size,
unsigned long __always_unused *park_size,
struct vdso_symtable __always_unused *sym_rt)
{
/* shouldn't be called on !CONFIG_COMPAT */
BUG();
return 0;
}
int __vdso_fill_symtable(uintptr_t mem, size_t size,
......
......@@ -1125,7 +1125,7 @@ long __export_restore_task(struct task_restore_args *args)
if (args->compatible_mode) {
/* Map compatible vdso */
if (vdso_map_compat(args->vdso_rt_parked_at,
vdso_rt_size, &args->vdso_sym_rt))
&vdso_rt_size, &args->vdso_sym_rt))
goto core_restore_end;
}
......
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