[CRIU] [PATCH 3/4] vdso: Rework vdso processing files
Laurent Dufour
ldufour at linux.vnet.ibm.com
Tue Sep 15 07:42:24 PDT 2015
On 15/09/2015 15:54, Christopher Covington wrote:
> Hi Laurent,
>
> On 09/03/2015 10:26 AM, Laurent Dufour wrote:
>> There were multiple copy of the same code spread over the different
>> architectures handling the vDSO.
>>
>> This patch is merging the duplicated code in arch/*/vdso-pie.c and
>> arch/*/include/asm/vdso.h in the common files and let only the architecture
>> specific part in the arch/*/* files.
>
> Thanks for doing this! I've finally taken these changes for a spin and found
> the following issue.
Hi Christopher,
Thanks for debugging my stuff :)
>
>> diff --git a/arch/aarch64/vdso-pie.c b/arch/aarch64/vdso-pie.c
>> index c6558378db1d..0f06c2d191d1 100644
>> --- a/arch/aarch64/vdso-pie.c
>> +++ b/arch/aarch64/vdso-pie.c
>> @@ -1,23 +1,10 @@
>> -#include <stdlib.h>
>> -#include <stdio.h>
>> #include <unistd.h>
>> -#include <string.h>
>> -#include <elf.h>
>> -#include <fcntl.h>
>> -#include <errno.h>
>> -
>> -#include <sys/types.h>
>> -#include <sys/stat.h>
>> -#include <sys/mman.h>
>>
>> #include "asm/string.h"
>> #include "asm/types.h"
>>
>> -#include "compiler.h"
>> #include "syscall.h"
>> -#include "image.h"
>> -#include "vdso.h"
>> -#include "vma.h"
>> +#include "parasite-vdso.h"
>> #include "log.h"
>> #include "bug.h"
>>
>> @@ -26,7 +13,7 @@
>> #endif
>> #define LOG_PREFIX "vdso: "
>>
>> -int vdso_redirect_calls(void *base_to, void *base_from,
>> +int vdso_redirect_calls(unsigned long base_to, unsigned long base_from,
>> struct vdso_symtable *to,
>> struct vdso_symtable *from)
>> {
>> @@ -37,8 +24,8 @@ int vdso_redirect_calls(void *base_to, void *base_from,
>> continue;
>>
>> pr_debug("br: %lx/%lx -> %lx/%lx (index %d)\n",
>> - (unsigned long)base_from, from->symbols[i].offset,
>> - (unsigned long)base_to, to->symbols[i].offset, i);
>> + base_from, from->symbols[i].offset,
>> + base_to, to->symbols[i].offset, i);
>>
>> write_intraprocedure_branch(base_to + to->symbols[i].offset,
>> base_from + from->symbols[i].offset);
>> @@ -46,383 +33,3 @@ int vdso_redirect_calls(void *base_to, void *base_from,
>>
>> return 0;
>> }
>> -
>> -
>> -/* Check if pointer is out-of-bound */
>> -static bool __ptr_oob(void *ptr, void *start, size_t size)
>> -{
>> - void *end = (void *)((unsigned long)start + size);
>> - return ptr > end || ptr < start;
>> -}
>> -
>> -/*
>> - * Elf hash, see format specification.
>> - */
>> -static unsigned long elf_hash(const unsigned char *name)
>> -{
>> - unsigned long h = 0, g;
>> -
>> - while (*name) {
>> - h = (h << 4) + *name++;
>> - g = h & 0xf0000000ul;
>> - if (g)
>> - h ^= g >> 24;
>> - h &= ~g;
>> - }
>> - return h;
>> -}
>> -
>> -int vdso_fill_symtable(char *mem, size_t size, struct vdso_symtable *t)
>> -{
>> - Elf64_Phdr *dynamic = NULL, *load = NULL;
>> - Elf64_Ehdr *ehdr = (void *)mem;
>> - Elf64_Dyn *dyn_strtab = NULL;
>> - Elf64_Dyn *dyn_symtab = NULL;
>> - Elf64_Dyn *dyn_strsz = NULL;
>> - Elf64_Dyn *dyn_syment = NULL;
>> - Elf64_Dyn *dyn_hash = NULL;
>> - Elf64_Word *hash = NULL;
>> - Elf64_Phdr *phdr;
>> - Elf64_Dyn *d;
>> -
>> - Elf64_Word *bucket, *chain;
>> - Elf64_Word nbucket, nchain;
>> -
>> - /*
>> - * See Elf specification for this magic values.
>> - */
>> - const char elf_ident[] = {
>> - 0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00,
>> - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>> - };
>> -
>> - const char *vdso_symbols[VDSO_SYMBOL_MAX] = {
>> - [VDSO_SYMBOL_CLOCK_GETRES] = VDSO_SYMBOL_CLOCK_GETRES_NAME,
>> - [VDSO_SYMBOL_CLOCK_GETTIME] = VDSO_SYMBOL_CLOCK_GETTIME_NAME,
>> - [VDSO_SYMBOL_GETTIMEOFDAY] = VDSO_SYMBOL_GETTIMEOFDAY_NAME,
>> - [VDSO_SYMBOL_RT_SIGRETURN] = VDSO_SYMBOL_RT_SIGRETURN_NAME,
>> - };
>
> I need to debug further, but I think the code that replaced this is somehow
> not properly position independent when I build for AArch64 and run. I'm
> getting a segfault. The faulting address (for example 0x000055d8) is
> vdso_symbols[0].
The function vdso_fill_symtable has been moved to pie/util-vdso.c which
is built twice, for criu (not requiring position independent code), for
the parasite code in position independent code.
I took a look to the pie/Makefile file and the -fpie GCC's option should
be raised for aarch64:
ifneq ($(filter-out i386 ia32, $(ARCH)),)
cflags-y += -DCR_NOGLIBC -fpie -Wa,--noexecstack -fno-stack-protector
else
...
This being said, my understanding is that the restarted process is
getting a segfault when it tries to access the vDSO, in this case, this
may be due to the trampoline code, in arch/aarch64/intraprocedure.S, but
that part has not been touched.
The only change I see in this area, which may impact, is the type of the
vdso_redirect_calls()'s parameters base_to and base_from, changed from
void* to unsigned long. This was required since these parameters are
used to compute pointers using the + operator.
Regarding vdso_redirect_calls() it is built only once (in PIE mode)
since it is only used in the parasite's context.
>
> Some corresponding debug output I added:
>
> pie: vdso: pc = 0x13b58
> pie: vdso: vdso_symbols = 0x146e8
> pie: vdso: vdso_symbols[0] = 0x55d8
What about the output printed in vdso_redirect_calls() ?
pr_debug("br: %lx/%lx -> %lx/%lx (index %d)\n",
base_from, from->symbols[i].offset,
base_to, to->symbols[i].offset, i);
> I'll keep investigating, but any suggested anyone has would be appreciated.
I'm available on the irc channel #criu on freenode, nickame ldu4, if you
want more interactive help here...
By the way, did you patch the kernel to track the vDSO remap operation ?
Cheers,
Laurent.
>
> I see this with both 4k and 64k pages (4k version above).
>
> Thanks,
> Christopher Covington
>
More information about the CRIU
mailing list