@@ -2973,14 +2973,23 @@ bool UnwindCursor<A, R>::isReadableAddr(const pint_t addr) const {
2973
2973
// which is Copyright Abseil Authors (2017), and provided under
2974
2974
// the Apache License 2.0.
2975
2975
2976
- // We have to check that addr is nullptr (0) because sigprocmask allows that
2977
- // as an argument without failure.
2978
- if (addr == 0 )
2979
- return false ;
2980
2976
// Align to 8-bytes.
2981
2977
const auto alignedAddr = addr & ~pint_t {7 };
2982
2978
const auto sigsetAddr = reinterpret_cast <sigset_t *>(alignedAddr);
2983
- [[maybe_unused]] int Result = sigprocmask (/* how=*/ -1 , sigsetAddr, nullptr );
2979
+ // We have to check that addr is nullptr because sigprocmask allows that
2980
+ // as an argument without failure.
2981
+ if (!sigsetAddr)
2982
+ return false ;
2983
+
2984
+ // We MUST use the raw sigprocmask syscall here, as wrappers may try to
2985
+ // access sigsetAddr which may cause a SIGSEGV. The raw syscall however is
2986
+ // safe. Additionally, we need to pass the kernel_sigset_size, which is
2987
+ // different from libc sizeof(sigset_t). Some archs have sigset_t
2988
+ // defined as unsigned long, so let's use that.
2989
+ const auto approxKernelSigsetSize = sizeof (unsigned long );
2990
+ [[maybe_unused]] int Result =
2991
+ syscall (SYS_rt_sigprocmask, /* how=*/ ~0 , sigsetAddr, sigsetAddr,
2992
+ approxKernelSigsetSize);
2984
2993
// Because our "how" is invalid, this syscall should always fail, and our
2985
2994
// errno should always be EINVAL or an EFAULT. EFAULT is not guaranteed
2986
2995
// by the POSIX standard, so this is (for now) Linux specific.
0 commit comments