RFR 8224676: Java crash if VSYSCALL is missing

Vladimir Kempik vkempik at azul.com
Thu May 23 15:23:57 UTC 2019


Hello,

Please review the following patch to address the issue:

Bug: https://bugs.openjdk.java.net/browse/JDK-8224676

Webrev: http://cr.openjdk.java.net/~vkempik/8224676/webrev.00/

Summary:
Java (and epecially ZGC) is using VSYSCALL linux kernel functionality to get cpu-id for a thread, basically to know on which cpu current thread is running.
A relevant peace of code:


int os::Linux::sched_getcpu_syscall(void) {
  unsigned int cpu = 0;
  int retval = -1;

#if defined(IA32)
  #ifndef SYS_getcpu
    #define SYS_getcpu 318
  #endif
  retval = syscall(SYS_getcpu, &cpu, NULL, NULL);
#elif defined(AMD64)
// Unfortunately we have to bring all these macros here from vsyscall.h
// to be able to compile on old linuxes.
  #define __NR_vgetcpu 2
  #define VSYSCALL_START (-10UL << 20)
  #define VSYSCALL_SIZE 1024
  #define VSYSCALL_ADDR(vsyscall_nr) (VSYSCALL_START+VSYSCALL_SIZE*(vsyscall_nr))
  typedef long (*vgetcpu_t)(unsigned int *cpu, unsigned int *node, unsigned long *tcache);
  vgetcpu_t vgetcpu = (vgetcpu_t)VSYSCALL_ADDR(__NR_vgetcpu);
  retval = vgetcpu(&cpu, NULL, NULL);
#endif


In x86 linux it’s going syscall way, which is a bit slow due to context switching.
on linux x86_64 it’s using VSYSCALL functionality, which is basically a page at fixed address which can execute 3 different syscalls (their analogues in user space) without context switch, in a very fast way.

VSYSCALL functionality is known to be insecure when ASLR is used, hence it’s being disabled sometimes.
For example in alpine linux it’s disabled by default and even its emulation (via a trap) by kernel is disabled. So one can’t use VSYSCALL at all and java crashes.

There is two ways to work it around: unify x86 and x86_64 routines and go syscall always (could be slow) or use functionality similar to vdso (it’s similar to VSYSCALL but the page is at different address on every app launch).

There is no low cost way to find out if VSYSCALL functionality is present  or not.
This patch remove VSYSCALL functionality and does perform simple asm instruction to get cpu id.
it’s very imilar to what happens in vgetcpu function in vdso: https://elixir.bootlin.com/linux/v4.4/source/arch/x86/include/asm/vgtod.h#L77

Regards, Vladimir


More information about the hotspot-runtime-dev mailing list