aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFangrui Song <maskray@google.com>2023-12-20 11:47:37 -0800
committerCopybara-Service <copybara-worker@google.com>2023-12-20 11:48:40 -0800
commit7a1898a04fb3ab83b869e7967ddd7721696490a3 (patch)
tree897bf0fc86b71f17e42603c11c0c80b5c232128a
parent299dbc588e4d2a6e23a4f99d5d224c042ab4a9a5 (diff)
downloadabseil-cpp-7a1898a04fb3ab83b869e7967ddd7721696490a3.tar.gz
AddressIsReadable: improve comments
Linux kernel's rt_sigprocmask correctly handles an unaligned user address[1]. The original issue was for qemu-user, which seems long irrelevant. Tested locally on an AArch64 CPU and qemu-aarch64-static. The alignment operation actually serves another purpose: when addr resides in the last 7 bytes of a page (unaligned), check only the current page and not the next. Update the comment. [1]: kernel/signal.c `SYSCALL_DEFINE4(rt_sigprocmask` arch/arm64/include/asm/uaccess.h:raw_copy_from_user arch/arm64/lib/copy_template.S "alignment handled by the hardware" PiperOrigin-RevId: 592618320 Change-Id: Ifbd05aba42f46e36e710cca940570213036b3ce0
-rw-r--r--absl/debugging/internal/address_is_readable.cc6
1 files changed, 4 insertions, 2 deletions
diff --git a/absl/debugging/internal/address_is_readable.cc b/absl/debugging/internal/address_is_readable.cc
index 91eaa76f..be17a105 100644
--- a/absl/debugging/internal/address_is_readable.cc
+++ b/absl/debugging/internal/address_is_readable.cc
@@ -50,8 +50,10 @@ namespace debugging_internal {
// NOTE: any new system calls here may also require sandbox reconfiguration.
//
bool AddressIsReadable(const void *addr) {
- // Align address on 8-byte boundary. On aarch64, checking last
- // byte before inaccessible page returned unexpected EFAULT.
+ // rt_sigprocmask below checks 8 contiguous bytes. If addr resides in the
+ // last 7 bytes of a page (unaligned), rt_sigprocmask would additionally
+ // check the readability of the next page, which is not desired. Align
+ // address on 8-byte boundary to check only the current page.
const uintptr_t u_addr = reinterpret_cast<uintptr_t>(addr) & ~uintptr_t{7};
addr = reinterpret_cast<const void *>(u_addr);