From 99e395e3b1379c12a382544d597dc12bd9293592 Mon Sep 17 00:00:00 2001 From: Bin Lu Date: Fri, 28 Feb 2020 14:52:01 +0800 Subject: passed the syscall test case 'clock_getres' on Arm64 platform Test command: bazel test //test/syscalls:clock_getres_test_runsc_ptrace Signed-off-by: Bin Lu --- vdso/vdso.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'vdso/vdso.cc') diff --git a/vdso/vdso.cc b/vdso/vdso.cc index 8bb80a7a4..c2585d592 100644 --- a/vdso/vdso.cc +++ b/vdso/vdso.cc @@ -126,6 +126,10 @@ extern "C" int __kernel_clock_getres(clockid_t clock, struct timespec* res) { case CLOCK_REALTIME: case CLOCK_MONOTONIC: case CLOCK_BOOTTIME: { + if (res == nullptr) { + return 0; + } + res->tv_sec = 0; res->tv_nsec = 1; break; -- cgit v1.2.3 From fe001edb14e6e879ab4ebca0d2ac71d770ac8cce Mon Sep 17 00:00:00 2001 From: Bin Lu Date: Tue, 11 Feb 2020 02:35:39 -0500 Subject: Arm64: VDSO support for signal The vdso is enabled, so we can use the sigreturn trampolines the vdso provides in arch module. Signed-off-by: Bin Lu --- pkg/sentry/loader/loader.go | 9 +++++++++ pkg/sentry/loader/vdso.go | 25 +++++++++++++++++++++++++ vdso/syscalls.h | 25 +++++++++++++------------ vdso/vdso.cc | 12 ++++++------ vdso/vdso_amd64.lds | 1 + 5 files changed, 54 insertions(+), 18 deletions(-) (limited to 'vdso/vdso.cc') diff --git a/pkg/sentry/loader/loader.go b/pkg/sentry/loader/loader.go index 9a613d6b7..57422706d 100644 --- a/pkg/sentry/loader/loader.go +++ b/pkg/sentry/loader/loader.go @@ -392,6 +392,15 @@ func Load(ctx context.Context, args LoadArgs, extraAuxv []arch.AuxEntry, vdso *V m.SetAuxv(auxv) m.SetExecutable(d) + symbolValue, err := getSymbolValueFromVDSO("rt_sigreturn") + if err != nil { + return 0, nil, "", syserr.NewDynamic(fmt.Sprintf("Failed to find rt_sigreturn in vdso: %v", err), syserr.FromError(err).ToLinux()) + } + + // Found rt_sigretrun. + addr := uint64(vdsoAddr) + symbolValue - vdsoPrelink + m.SetVDSOSigReturn(addr) + ac.SetIP(uintptr(loaded.entry)) ac.SetStack(uintptr(stack.Bottom)) diff --git a/pkg/sentry/loader/vdso.go b/pkg/sentry/loader/vdso.go index 52f446ed7..01eaefd26 100644 --- a/pkg/sentry/loader/vdso.go +++ b/pkg/sentry/loader/vdso.go @@ -15,9 +15,11 @@ package loader import ( + "bytes" "debug/elf" "fmt" "io" + "strings" "gvisor.dev/gvisor/pkg/abi" "gvisor.dev/gvisor/pkg/context" @@ -37,6 +39,8 @@ import ( "gvisor.dev/gvisor/pkg/waiter" ) +const vdsoPrelink = 0xffffffffff700000 + type fileContext struct { context.Context } @@ -218,6 +222,27 @@ type VDSO struct { phdrs []elf.ProgHeader `state:".([]elfProgHeader)"` } +// getSymbolValueFromVDSO returns the specific symbol value in vdso.so. +func getSymbolValueFromVDSO(symbol string) (uint64, error) { + f, err := elf.NewFile(bytes.NewReader(vdsoBin)) + if err != nil { + return 0, err + } + syms, err := f.Symbols() + if err != nil { + return 0, err + } + + for _, sym := range syms { + if elf.ST_BIND(sym.Info) != elf.STB_LOCAL && sym.Section != elf.SHN_UNDEF { + if strings.Contains(sym.Name, symbol) { + return sym.Value, nil + } + } + } + return 0, fmt.Errorf("no %v in vdso.so", symbol) +} + // PrepareVDSO validates the system VDSO and returns a VDSO, containing the // param page for updating by the kernel. func PrepareVDSO(ctx context.Context, mfp pgalloc.MemoryFileProvider) (*VDSO, error) { diff --git a/vdso/syscalls.h b/vdso/syscalls.h index b6d15a7d3..f630ae563 100644 --- a/vdso/syscalls.h +++ b/vdso/syscalls.h @@ -26,6 +26,9 @@ #include #include +#define __stringify_1(x...) #x +#define __stringify(x...) __stringify_1(x) + namespace vdso { #if __x86_64__ @@ -51,20 +54,13 @@ static inline int sys_getcpu(unsigned* cpu, unsigned* node, return num; } -#elif __aarch64__ - -static inline int sys_rt_sigreturn(void) { - int num = __NR_rt_sigreturn; - - asm volatile( - "mov x8, %0\n" - "svc #0 \n" - : "+r"(num) - : - :); - return num; +static inline void sys_rt_sigreturn(void) { + asm volatile("movl $" __stringify(__NR_rt_sigreturn)", %eax \n" + "syscall \n"); } +#elif __aarch64__ + static inline int sys_clock_gettime(clockid_t _clkid, struct timespec* _ts) { register struct timespec* ts asm("x1") = _ts; register clockid_t clkid asm("x0") = _clkid; @@ -91,6 +87,11 @@ static inline int sys_clock_getres(clockid_t _clkid, struct timespec* _ts) { return ret; } +static inline void sys_rt_sigreturn(void) { + asm volatile("mov x8, #" __stringify(__NR_rt_sigreturn)" \n" + "svc #0 \n"); +} + #else #error "unsupported architecture" #endif diff --git a/vdso/vdso.cc b/vdso/vdso.cc index 8bb80a7a4..62f59766d 100644 --- a/vdso/vdso.cc +++ b/vdso/vdso.cc @@ -69,6 +69,12 @@ int __common_gettimeofday(struct timeval* tv, struct timezone* tz) { } } // namespace +// __kernel_rt_sigreturn() implements rt_sigreturn() +extern "C" void __kernel_rt_sigreturn(unsigned long unused) { + // No optimizations yet, just make the real system call. + sys_rt_sigreturn(); +} + #if __x86_64__ // __vdso_clock_gettime() implements clock_gettime() @@ -139,12 +145,6 @@ extern "C" int __kernel_clock_getres(clockid_t clock, struct timespec* res) { return ret; } -// __kernel_rt_sigreturn() implements gettimeofday() -extern "C" int __kernel_rt_sigreturn(unsigned long unused) { - // No optimizations yet, just make the real system call. - return sys_rt_sigreturn(); -} - #else #error "unsupported architecture" #endif diff --git a/vdso/vdso_amd64.lds b/vdso/vdso_amd64.lds index e2615ae9e..d114290da 100644 --- a/vdso/vdso_amd64.lds +++ b/vdso/vdso_amd64.lds @@ -95,6 +95,7 @@ VERSION { __vdso_getcpu; time; __vdso_time; + __kernel_rt_sigreturn; local: *; }; -- cgit v1.2.3