Skip to content

Commit

Permalink
Merge pull request google#1818 from lubinszARM:pr_signal_1
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 307680200
  • Loading branch information
gvisor-bot committed Apr 21, 2020
2 parents 89822a4 + fe001ed commit eba0866
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 18 deletions.
9 changes: 9 additions & 0 deletions pkg/sentry/loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,15 @@ func Load(ctx context.Context, args LoadArgs, extraAuxv []arch.AuxEntry, vdso *V
m.SetAuxv(auxv)
m.SetExecutable(file)

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))

Expand Down
25 changes: 25 additions & 0 deletions pkg/sentry/loader/vdso.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
package loader

import (
"bytes"
"debug/elf"
"fmt"
"io"
"strings"

"gvisor.dev/gvisor/pkg/abi"
"gvisor.dev/gvisor/pkg/context"
Expand All @@ -38,6 +40,8 @@ import (
"gvisor.dev/gvisor/pkg/waiter"
)

const vdsoPrelink = 0xffffffffff700000

type fileContext struct {
context.Context
}
Expand Down Expand Up @@ -221,6 +225,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) {
Expand Down
25 changes: 13 additions & 12 deletions vdso/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
#include <stddef.h>
#include <sys/types.h>

#define __stringify_1(x...) #x
#define __stringify(x...) __stringify_1(x)

namespace vdso {

#if __x86_64__
Expand All @@ -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;
Expand All @@ -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
Expand Down
12 changes: 6 additions & 6 deletions vdso/vdso.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -143,12 +149,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
Expand Down
1 change: 1 addition & 0 deletions vdso/vdso_amd64.lds
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ VERSION {
__vdso_getcpu;
time;
__vdso_time;
__kernel_rt_sigreturn;

local: *;
};
Expand Down

0 comments on commit eba0866

Please sign in to comment.