RFR: 8266749: AArch64: Backtracing broken on PAC enabled systems [v3]
Vladimir Kempik
vkempik at openjdk.java.net
Tue May 25 16:11:54 UTC 2021
On Fri, 21 May 2021 11:07:14 GMT, Alan Hayward <github.com+4146708+a74nh at openjdk.org> wrote:
>> On PAC systems, native code may sign return addresses before saving
>> them to the stack. We must ensure we strip the any signed bits in
>> order to walk the stack.
>> Add extra asserts in places where we do not expect saved return
>> addresses to be signed.
>>
>> On non-PAC systems, all PAC instructions are treated as NOPs.
>>
>> On Apple, use the provided ptrauth interface instead of asm
>> as the compiler may optimise further.
>>
>> Fedora 33 compiles all distro packages using PAC. Running the distro
>> provided OpenJDK-latest in GDB on a PAC system:
>>
>> Thread 2 "java" hit Breakpoint 1, 0x0000fffff68d7fe4 in init_globals() ()
>> from /usr/lib/jvm/java-16-openjdk-16.0.1.0.9-1.rolling.fc33.aarch64-fastdebug/lib/server/libjvm.so
>> (gdb) call (int)pns($sp, $fp, $pc)
>>
>> "Executing pns"
>> Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
>> V [libjvm.so+0xe26fe4] init_globals()+0x10
>> C 0x006ffffff74750c4
>> C 0x0042fffff6a7f84c
>> C 0x0037fffff7fa0954
>> C 0x0030fffff7fa4540
>> C 0x0078fffff7d980c8
>>
>> OpenJDK with this patch at the same breakpoint:
>>
>> (gdb) call (int)pns($sp, $fp, $pc)
>> "Executing pns"
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
>> V [libjvm.so+0x189c47c] Threads::create_vm(JavaVMInitArgs*, bool*)+0x27c
>> V [libjvm.so+0xf527a0] JNI_CreateJavaVM+0xc0
>> C [libjli.so+0x3860] JavaMain+0x7c
>> C [libjli.so+0x732c] ThreadJavaMain+0xc
>> C [libpthread.so.0+0x80c8] start_thread+0xd8
>>
>> OpenJDK with this patch breakpointed at pd_hotspot_signal_handler:
>>
>> "Executing pns"
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
>> V [libjvm.so+0x148a730] PosixSignals::pd_hotspot_signal_handler(int, siginfo_t*, ucontext_t*, JavaThread*)+0x0
>> C [linux-vdso.so.1+0x80c] __kernel_rt_sigreturn+0x0
>> J 53 c1 jdk.internal.org.objectweb.asm.SymbolTable.addConstantUtf8(Ljava/lang/String;)I java.base (98 bytes) @ 0x0000ffffe159cc3c [0x0000ffffe159cb40+0x00000000000000fc]
>> j jdk.internal.org.objectweb.asm.SymbolTable.setMajorVersionAndClassName(ILjava/lang/String;)I+12 java.base
>> j jdk.internal.org.objectweb.asm.ClassWriter.visit(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V+20 java.base
>> j java.lang.invoke.InvokerBytecodeGenerator.classFilePrologue()Ljdk/internal/org/objectweb/asm/ClassWriter;+30 java.base
>> j java.lang.invoke.InvokerBytecodeGenerator.generateCustomizedCodeBytes()[B+1 java.base
>> j java.lang.invoke.InvokerBytecodeGenerator.generateCustomizedCode(Ljava/lang/invoke/LambdaForm;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MemberName;+27 java.base
>> j java.lang.invoke.LambdaForm.compileToBytecode()V+69 java.base
>> j java.lang.invoke.DirectMethodHandle.makePreparedLambdaForm(Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/LambdaForm;+792 java.base
>> j java.lang.invoke.DirectMethodHandle.preparedLambdaForm(Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/LambdaForm;+17 java.base
>> j java.lang.invoke.DirectMethodHandle.preparedLambdaForm(Ljava/lang/invoke/MemberName;Z)Ljava/lang/invoke/LambdaForm;+163 java.base
>> j java.lang.invoke.DirectMethodHandle.preparedLambdaForm(Ljava/lang/invoke/MemberName;)Ljava/lang/invoke/LambdaForm;+2 java.base
>> j java.lang.invoke.DirectMethodHandle.make(BLjava/lang/Class;Ljava/lang/invoke/MemberName;Ljava/lang/Class;)Ljava/lang/invoke/DirectMethodHandle;+159 java.base
>> j java.lang.invoke.MethodHandles$Lookup.getDirectMethodCommon(BLjava/lang/Class;Ljava/lang/invoke/MemberName;ZZLjava/lang/invoke/MethodHandles$Lookup;)Ljava/lang/invoke/MethodHandle;+210 java.base
>> j java.lang.invoke.MethodHandles$Lookup.getDirectMethodNoSecurityManager(BLjava/lang/Class;Ljava/lang/invoke/MemberName;Ljava/lang/invoke/MethodHandles$Lookup;)Ljava/lang/invoke/MethodHandle;+14 java.base
>> j java.lang.invoke.MethodHandles$Lookup.getDirectMethodForConstant(BLjava/lang/Class;Ljava/lang/invoke/MemberName;)Ljava/lang/invoke/MethodHandle;+31 java.base
>> j java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(BLjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;+153 java.base
>> j java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;+38 java.base
>> v ~StubRoutines::call_stub
>> V [libjvm.so+0xe20118] JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, Thread*)+0x5c8
>> V [libjvm.so+0xe20f64] JavaCalls::call_static(JavaValue*, Klass*, Symbol*, Symbol*, JavaCallArguments*, Thread*)+0x284
>> V [libjvm.so+0x184b778] SystemDictionary::link_method_handle_constant(Klass*, int, Klass*, Symbol*, Symbol*, Thread*)+0x398
>> V [libjvm.so+0xa1f104] ConstantPool::resolve_constant_at_impl(constantPoolHandle const&, int, int, bool*, Thread*)+0xca0
>> V [libjvm.so+0xa1fb6c] ConstantPool::copy_bootstrap_arguments_at_impl(constantPoolHandle const&, int, int, int, objArrayHandle, int, bool, Handle, Thread*)+0x3fc
>> V [libjvm.so+0x6bef6c] BootstrapInfo::resolve_args(Thread*)+0xcbc
>> V [libjvm.so+0x6c1538] BootstrapInfo::resolve_bsm(Thread*)+0x1194
>> V [libjvm.so+0x184d300] SystemDictionary::invoke_bootstrap_method(BootstrapInfo&, Thread*)+0x30
>> V [libjvm.so+0x120450c] LinkResolver::resolve_dynamic_call(CallInfo&, BootstrapInfo&, Thread*)+0x2c
>> V [libjvm.so+0x1204b1c] LinkResolver::resolve_invokedynamic(CallInfo&, constantPoolHandle const&, int, Thread*)+0x1bc
>> V [libjvm.so+0xe0ecc4] InterpreterRuntime::resolve_invokedynamic(JavaThread*)+0x190
>> V [libjvm.so+0xe123a0] InterpreterRuntime::resolve_from_cache(JavaThread*, Bytecodes::Code)+0x160
>> j jdk.internal.module.ModulePath.explodedPackages(Ljava/nio/file/Path;)Ljava/util/Set;+5 java.base
>> j jdk.internal.module.ModulePath.lambda$readExplodedModule$9(Ljava/nio/file/Path;)Ljava/util/Set;+2 java.base
>> j jdk.internal.module.ModulePath$$Lambda$2+0x000000010003bbe0.get()Ljava/lang/Object;+8 java.base
>> j jdk.internal.module.ModuleInfo.doRead(Ljava/io/DataInput;)Ljdk/internal/module/ModuleInfo$Attributes;+762 java.base
>> j jdk.internal.module.ModuleInfo.read(Ljava/io/InputStream;Ljava/util/function/Supplier;)Ljdk/internal/module/ModuleInfo$Attributes;+16 java.base
>> j jdk.internal.module.ModulePath.readExplodedModule(Ljava/nio/file/Path;)Ljava/lang/module/ModuleReference;+35 java.base
>> j jdk.internal.module.ModulePath.readModule(Ljava/nio/file/Path;Ljava/nio/file/attribute/BasicFileAttributes;)Ljava/lang/module/ModuleReference;+11 java.base
>> j jdk.internal.module.ModulePath.scanDirectory(Ljava/nio/file/Path;)Ljava/util/Map;+69 java.base
>> j jdk.internal.module.ModulePath.scan(Ljava/nio/file/Path;)Ljava/util/Map;+60 java.base
>> j jdk.internal.module.ModulePath.scanNextEntry()V+23 java.base
>> j jdk.internal.module.ModulePath.find(Ljava/lang/String;)Ljava/util/Optional;+36 java.base
>> j jdk.internal.module.SystemModuleFinders$1.lambda$find$0(Ljava/lang/module/ModuleFinder;Ljava/lang/String;)Ljava/util/Optional;+2 java.base
>> j jdk.internal.module.SystemModuleFinders$1$$Lambda$1+0x0000000100033b00.run()Ljava/lang/Object;+8 java.base
>> j java.security.AccessController.executePrivileged(Ljava/security/PrivilegedAction;Ljava/security/AccessControlContext;Ljava/lang/Class;)Ljava/lang/Object;+29 java.base
>> j java.security.AccessController.doPrivileged(Ljava/security/PrivilegedAction;)Ljava/lang/Object;+5 java.base
>> j jdk.internal.module.SystemModuleFinders$1.find(Ljava/lang/String;)Ljava/util/Optional;+12 java.base
>> j jdk.internal.module.ModuleBootstrap.boot2()Ljava/lang/ModuleLayer;+304 java.base
>> j jdk.internal.module.ModuleBootstrap.boot()Ljava/lang/ModuleLayer;+64 java.base
>> j java.lang.System.initPhase2(ZZ)I+0 java.base
>> v ~StubRoutines::call_stub
>> V [libjvm.so+0xe20118] JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, Thread*)+0x5c8
>> V [libjvm.so+0xe20f64] JavaCalls::call_static(JavaValue*, Klass*, Symbol*, Symbol*, JavaCallArguments*, Thread*)+0x284
>> V [libjvm.so+0x189c7bc] Threads::create_vm(JavaVMInitArgs*, bool*)+0x5bc
>> V [libjvm.so+0xf527a0] JNI_CreateJavaVM+0xc0
>> C [libjli.so+0x3860] JavaMain+0x7c
>> C [libjli.so+0x732c] ThreadJavaMain+0xc
>> C [libpthread.so.0+0x80c8] start_thread+0xd8
>
> Alan Hayward has updated the pull request incrementally with one additional commit since the last revision:
>
> Ensure pointer is stripped on macos
>
> Change-Id: Idcf5f08e87c1e1f5af1dc8f421f8c7efc3d9c4c2
> CustomizedGitHooks: yes
Hello
I don't think that's correct description of current PAC state on macos11
if binary is of type arm64e then it has pac enabled and it works. (most of system binaries are already arm64e, also the kernel and kernel extensions are arm64e already)
To be able to test your own arm64e binary one need to add to boot-args ( https://developer.apple.com/documentation/driverkit/debugging_and_testing_system_extensions?language=objc ) -arm64e_preview_abi, otherwise the kernel won't allow custom arm64e app to start.
But, there is one thing, the shared library cache is arm64e only ( check folder /System/Library/dyld), and all of few remaining dylibs ( check any in /usr/lib) is arm64e only ( plus x86_64). arm64 apps use arm64e libs.
All of these arm64e libs use PAC and it works ( not disabled/NOP-ed), as a result we had a bug recently - https://bugs.openjdk.java.net/browse/JDK-8267235
jvm probably needs to sanitize any pointer coming from native libs.
-------------
PR: https://git.openjdk.java.net/jdk/pull/4029
More information about the hotspot-dev
mailing list