8266749: AArch64: Backtracing broken on PAC enabled systems

Reviewed-by: gziemski, aph
This commit is contained in:
Alan Hayward 2021-06-08 02:24:43 +00:00 committed by Ningsheng Jian
parent 36c4e5f264
commit ae986bc8df
7 changed files with 180 additions and 5 deletions

View file

@ -272,6 +272,9 @@ void frame::patch_pc(Thread* thread, address pc) {
tty->print_cr("patch_pc at address " INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "]",
p2i(pc_addr), p2i(*pc_addr), p2i(pc));
}
// Only generated code frames should be patched, therefore the return address will not be signed.
assert(pauth_ptr_is_raw(*pc_addr), "cannot be signed");
// Either the return address is the original one or we are going to
// patch in the same address that's already there.
assert(_pc == *pc_addr || pc == *pc_addr, "must be");
@ -446,7 +449,9 @@ frame frame::sender_for_interpreter_frame(RegisterMap* map) const {
}
#endif // COMPILER2_OR_JVMCI
return frame(sender_sp, unextended_sp, link(), sender_pc());
// Use the raw version of pc - the interpreter should not have signed it.
return frame(sender_sp, unextended_sp, link(), sender_pc_maybe_signed());
}
@ -509,6 +514,7 @@ frame frame::sender_raw(RegisterMap* map) const {
// Must be native-compiled frame, i.e. the marshaling code for native
// methods that exists in the core system.
return frame(sender_sp(), link(), sender_pc());
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -149,6 +149,7 @@
intptr_t* fp() const { return _fp; }
inline address* sender_pc_addr() const;
inline address sender_pc_maybe_signed() const;
// expression stack tos if we are nested in a java call
intptr_t* interpreter_frame_last_sp() const;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -28,6 +28,7 @@
#include "code/codeCache.hpp"
#include "code/vmreg.inline.hpp"
#include "pauth_aarch64.hpp"
// Inline functions for AArch64 frames:
@ -45,6 +46,7 @@ inline frame::frame() {
static int spin;
inline void frame::init(intptr_t* sp, intptr_t* fp, address pc) {
assert(pauth_ptr_is_raw(pc), "cannot be signed");
intptr_t a = intptr_t(sp);
intptr_t b = intptr_t(fp);
_sp = sp;
@ -69,6 +71,7 @@ inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) {
}
inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc) {
assert(pauth_ptr_is_raw(pc), "cannot be signed");
intptr_t a = intptr_t(sp);
intptr_t b = intptr_t(fp);
_sp = sp;
@ -150,8 +153,9 @@ inline intptr_t* frame::unextended_sp() const { return _unextended_sp; }
// Return address:
inline address* frame::sender_pc_addr() const { return (address*) addr_at( return_addr_offset); }
inline address frame::sender_pc() const { return *sender_pc_addr(); }
inline address* frame::sender_pc_addr() const { return (address*) addr_at( return_addr_offset); }
inline address frame::sender_pc_maybe_signed() const { return *sender_pc_addr(); }
inline address frame::sender_pc() const { return pauth_strip_pointer(sender_pc_maybe_signed()); }
inline intptr_t* frame::sender_sp() const { return addr_at( sender_sp_offset); }

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2021, Arm Limited. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef CPU_AARCH64_PAUTH_AARCH64_INLINE_HPP
#define CPU_AARCH64_PAUTH_AARCH64_INLINE_HPP
#include OS_CPU_HEADER_INLINE(pauth)
inline bool pauth_ptr_is_raw(address ptr) {
// Confirm none of the high bits are set in the pointer.
return ptr == pauth_strip_pointer(ptr);
}
#endif // CPU_AARCH64_PAUTH_AARCH64_INLINE_HPP

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2021, Arm Limited. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef OS_CPU_LINUX_AARCH64_PAUTH_BSD_AARCH64_INLINE_HPP
#define OS_CPU_LINUX_AARCH64_PAUTH_BSD_AARCH64_INLINE_HPP
#ifdef __APPLE__
#include <ptrauth.h>
#endif
// Only the PAC instructions in the NOP space can be used. This ensures the
// binaries work on systems without PAC. Write these instructions using their
// alternate "hint" instructions to ensure older compilers can still be used.
// For Apple, use the provided interface as this may provide additional
// optimization.
#define XPACLRI "hint #0x7;"
inline address pauth_strip_pointer(address ptr) {
#ifdef __APPLE__
return ptrauth_strip(ptr, ptrauth_key_asib);
#else
register address result __asm__("x30") = ptr;
asm (XPACLRI : "+r"(result));
return result;
#endif
}
#undef XPACLRI
#endif // OS_CPU_LINUX_AARCH64_PAUTH_BSD_AARCH64_INLINE_HPP

View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2021, Arm Limited. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef OS_CPU_LINUX_AARCH64_PAUTH_LINUX_AARCH64_INLINE_HPP
#define OS_CPU_LINUX_AARCH64_PAUTH_LINUX_AARCH64_INLINE_HPP
// Only the PAC instructions in the NOP space can be used. This ensures the
// binaries work on systems without PAC. Write these instructions using their
// alternate "hint" instructions to ensure older compilers can still be used.
#define XPACLRI "hint #0x7;"
inline address pauth_strip_pointer(address ptr) {
register address result __asm__("x30") = ptr;
asm (XPACLRI : "+r"(result));
return result;
}
#undef XPACLRI
#endif // OS_CPU_LINUX_AARCH64_PAUTH_LINUX_AARCH64_INLINE_HPP

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2021, Arm Limited. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef OS_CPU_LINUX_AARCH64_PAUTH_WINDOWS_AARCH64_INLINE_HPP
#define OS_CPU_LINUX_AARCH64_PAUTH_WINDOWS_AARCH64_INLINE_HPP
inline address pauth_strip_pointer(address ptr) {
// No PAC support in windows as of yet.
return ptr;
}
#endif // OS_CPU_LINUX_AARCH64_PAUTH_WINDOWS_AARCH64_INLINE_HPP