diff options
Diffstat (limited to 'libc')
-rw-r--r-- | libc/bionic/abort.cpp | 9 | ||||
-rw-r--r-- | libc/bionic/sigaction.cpp | 50 | ||||
-rw-r--r-- | libc/bionic/signal.cpp | 37 | ||||
-rw-r--r-- | libc/bionic/spawn.cpp | 8 | ||||
-rw-r--r-- | libc/include/signal.h | 63 | ||||
-rw-r--r-- | libc/libc.arm.map | 1 | ||||
-rw-r--r-- | libc/libc.arm64.map | 1 | ||||
-rw-r--r-- | libc/libc.map.txt | 1 | ||||
-rw-r--r-- | libc/libc.mips.map | 1 | ||||
-rw-r--r-- | libc/libc.mips64.map | 1 | ||||
-rw-r--r-- | libc/libc.x86.map | 1 | ||||
-rw-r--r-- | libc/libc.x86_64.map | 1 | ||||
-rw-r--r-- | libc/malloc_debug/BacktraceData.cpp | 14 | ||||
-rw-r--r-- | libc/malloc_debug/RecordData.cpp | 7 |
14 files changed, 110 insertions, 85 deletions
diff --git a/libc/bionic/abort.cpp b/libc/bionic/abort.cpp index ec26a50c4..d2c99a5ca 100644 --- a/libc/bionic/abort.cpp +++ b/libc/bionic/abort.cpp @@ -67,13 +67,10 @@ void abort() { sigprocmask64(SIG_SETMASK, &mask, nullptr); inline_tgkill(pid, tid, SIGABRT); - // If SIGABRT ignored, or caught and the handler returns, + // If SIGABRT is ignored or it's caught and the handler returns, // remove the SIGABRT signal handler and raise SIGABRT again. - struct sigaction sa; - sa.sa_handler = SIG_DFL; - sa.sa_flags = SA_RESTART; - sigemptyset(&sa.sa_mask); - sigaction(SIGABRT, &sa, &sa); + struct sigaction64 sa = { .sa_handler = SIG_DFL, .sa_flags = SA_RESTART }; + sigaction64(SIGABRT, &sa, nullptr); sigprocmask64(SIG_SETMASK, &mask, nullptr); inline_tgkill(pid, tid, SIGABRT); diff --git a/libc/bionic/sigaction.cpp b/libc/bionic/sigaction.cpp index 0633748bf..e5a7d5f2c 100644 --- a/libc/bionic/sigaction.cpp +++ b/libc/bionic/sigaction.cpp @@ -27,6 +27,7 @@ */ #include <signal.h> +#include <string.h> extern "C" void __restore_rt(void); extern "C" void __restore(void); @@ -75,28 +76,49 @@ int sigaction(int signal, const struct sigaction* bionic_new_action, struct siga return result; } +__strong_alias(sigaction64, sigaction); + #else +extern "C" int __rt_sigaction(int, const struct sigaction64*, struct sigaction64*, size_t); extern "C" int __sigaction(int, const struct sigaction*, struct sigaction*); -int sigaction(int signal, const struct sigaction* bionic_new_action, struct sigaction* bionic_old_action) { +int sigaction(int signal, const struct sigaction* bionic_new, struct sigaction* bionic_old) { // The 32-bit ABI is broken. struct sigaction includes a too-small sigset_t, - // so we have to use sigaction(2) rather than rt_sigaction(2). - struct sigaction kernel_new_action; - if (bionic_new_action != NULL) { - kernel_new_action.sa_flags = bionic_new_action->sa_flags; - kernel_new_action.sa_handler = bionic_new_action->sa_handler; - kernel_new_action.sa_mask = bionic_new_action->sa_mask; -#if defined(SA_RESTORER) - kernel_new_action.sa_restorer = bionic_new_action->sa_restorer; + // so we have to translate to struct sigaction64 first. + struct sigaction64 kernel_new; + if (bionic_new) { + kernel_new = {}; + kernel_new.sa_flags = bionic_new->sa_flags; + kernel_new.sa_handler = bionic_new->sa_handler; + memcpy(&kernel_new.sa_mask, &bionic_new->sa_mask, sizeof(bionic_new->sa_mask)); + } - if (!(kernel_new_action.sa_flags & SA_RESTORER)) { - kernel_new_action.sa_flags |= SA_RESTORER; - kernel_new_action.sa_restorer = (kernel_new_action.sa_flags & SA_SIGINFO) ? &__restore_rt : &__restore; + struct sigaction64 kernel_old; + int result = sigaction64(signal, bionic_new ? &kernel_new : nullptr, &kernel_old); + if (bionic_old) { + *bionic_old = {}; + bionic_old->sa_flags = kernel_old.sa_flags; + bionic_old->sa_handler = kernel_old.sa_handler; + memcpy(&bionic_old->sa_mask, &kernel_old.sa_mask, sizeof(bionic_old->sa_mask)); + } + return result; +} + +int sigaction64(int signal, const struct sigaction64* bionic_new, struct sigaction64* bionic_old) { + struct sigaction64 kernel_new; + if (bionic_new) { + kernel_new = *bionic_new; + if (!(kernel_new.sa_flags & SA_RESTORER)) { + kernel_new.sa_flags |= SA_RESTORER; + kernel_new.sa_restorer = (kernel_new.sa_flags & SA_SIGINFO) ? &__restore_rt : &__restore; } -#endif } - return __sigaction(signal, (bionic_new_action != NULL) ? &kernel_new_action : NULL, bionic_old_action); + + return __rt_sigaction(signal, + bionic_new ? &kernel_new : nullptr, + bionic_old, + sizeof(kernel_new.sa_mask)); } #endif diff --git a/libc/bionic/signal.cpp b/libc/bionic/signal.cpp index 099944ad8..fbfe0ce24 100644 --- a/libc/bionic/signal.cpp +++ b/libc/bionic/signal.cpp @@ -147,22 +147,19 @@ int sighold(int sig) { } int sigignore(int sig) { - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - if (sigemptyset(&sa.sa_mask) == -1) return -1; - sa.sa_handler = SIG_IGN; - return sigaction(sig, &sa, nullptr); + struct sigaction64 sa = { .sa_handler = SIG_IGN }; + return sigaction64(sig, &sa, nullptr); } int siginterrupt(int sig, int flag) { - struct sigaction act; - sigaction(sig, nullptr, &act); + struct sigaction64 act; + sigaction64(sig, nullptr, &act); if (flag) { act.sa_flags &= ~SA_RESTART; } else { act.sa_flags |= SA_RESTART; } - return sigaction(sig, &act, nullptr); + return sigaction64(sig, &act, nullptr); } template <typename SigSetT> @@ -185,16 +182,8 @@ int sigismember64(const sigset64_t* set, int sig) { } __LIBC_HIDDEN__ sighandler_t _signal(int sig, sighandler_t handler, int flags) { - struct sigaction sa; - sigemptyset(&sa.sa_mask); - sa.sa_handler = handler; - sa.sa_flags = flags; - - if (sigaction(sig, &sa, &sa) == -1) { - return SIG_ERR; - } - - return sa.sa_handler; + struct sigaction64 sa = { .sa_handler = handler, .sa_flags = flags }; + return (sigaction64(sig, &sa, &sa) == -1) ? SIG_ERR : sa.sa_handler; } sighandler_t signal(int sig, sighandler_t handler) { @@ -262,15 +251,11 @@ int sigrelse(int sig) { } sighandler_t sigset(int sig, sighandler_t disp) { - struct sigaction new_sa; - if (disp != SIG_HOLD) { - memset(&new_sa, 0, sizeof(new_sa)); - new_sa.sa_handler = disp; - sigemptyset(&new_sa.sa_mask); - } + struct sigaction64 new_sa; + if (disp != SIG_HOLD) new_sa = { .sa_handler = disp }; - struct sigaction old_sa; - if (sigaction(sig, (disp == SIG_HOLD) ? nullptr : &new_sa, &old_sa) == -1) { + struct sigaction64 old_sa; + if (sigaction64(sig, (disp == SIG_HOLD) ? nullptr : &new_sa, &old_sa) == -1) { return SIG_ERR; } diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp index 7422a0bb4..fde102cb7 100644 --- a/libc/bionic/spawn.cpp +++ b/libc/bionic/spawn.cpp @@ -98,17 +98,17 @@ static void ApplyAttrs(short flags, const posix_spawnattr_t* attr) { // POSIX: "Signals set to be caught by the calling process shall be // set to the default action in the child process." bool use_sigdefault = ((flags & POSIX_SPAWN_SETSIGDEF) != 0); - const struct sigaction default_sa = { .sa_handler = SIG_DFL }; + const struct sigaction64 default_sa = { .sa_handler = SIG_DFL }; for (int s = 1; s < _NSIG; ++s) { bool reset = false; if (use_sigdefault && sigismember64(&(*attr)->sigdefault.sigset64, s)) { reset = true; } else { - struct sigaction current; - if (sigaction(s, nullptr, ¤t) == -1) _exit(127); + struct sigaction64 current; + if (sigaction64(s, nullptr, ¤t) == -1) _exit(127); reset = (current.sa_handler != SIG_IGN && current.sa_handler != SIG_DFL); } - if (reset && sigaction(s, &default_sa, nullptr) == -1) _exit(127); + if (reset && sigaction64(s, &default_sa, nullptr) == -1) _exit(127); } if ((flags & POSIX_SPAWN_SETPGROUP) != 0 && setpgid(0, (*attr)->pgroup) == -1) _exit(127); diff --git a/libc/include/signal.h b/libc/include/signal.h index 61bb395fa..2027d70cb 100644 --- a/libc/include/signal.h +++ b/libc/include/signal.h @@ -40,7 +40,8 @@ /* For 64-bit (and mips), the kernel's struct sigaction doesn't match the * POSIX one, so we need to expose our own and translate behind the scenes. * For 32-bit, we're stuck with the definitions we already shipped, - * even though they contain a sigset_t that's too small. */ + * even though they contain a sigset_t that's too small. See sigaction64. + */ #define sigaction __kernel_sigaction #include <linux/signal.h> #undef sigaction @@ -89,43 +90,65 @@ typedef struct { unsigned long __bits[_KERNEL__NSIG/LONG_BIT]; } sigset64_t; #if defined(__LP64__) +#define __SIGACTION_BODY \ + int sa_flags; \ + union { \ + sighandler_t sa_handler; \ + void (*sa_sigaction)(int, struct siginfo*, void*); \ + }; \ + sigset_t sa_mask; \ + void (*sa_restorer)(void); \ + +struct sigaction { __SIGACTION_BODY }; +struct sigaction64 { __SIGACTION_BODY }; + +#undef __SIGACTION_BODY + +#elif defined(__mips__) + +#define __SIGACTION_BODY \ + int sa_flags; \ + union { \ + sighandler_t sa_handler; \ + void (*sa_sigaction)(int, struct siginfo*, void*); \ + }; \ + sigset_t sa_mask; \ + +struct sigaction { __SIGACTION_BODY }; +struct sigaction64 { __SIGACTION_BODY }; + +#undef __SIGACTION_BODY + +#else + +#undef sa_handler +#undef sa_sigaction + struct sigaction { - int sa_flags; union { sighandler_t sa_handler; void (*sa_sigaction)(int, struct siginfo*, void*); }; sigset_t sa_mask; + int sa_flags; void (*sa_restorer)(void); }; -#elif defined(__mips__) - -struct sigaction { - int sa_flags; +/* This matches the kernel's internal structure. */ +struct sigaction64 { union { sighandler_t sa_handler; - void (*sa_sigaction) (int, struct siginfo*, void*); + void (*sa_sigaction)(int, struct siginfo*, void*); }; - sigset_t sa_mask; -}; - -#else - -struct sigaction { - union { - sighandler_t _sa_handler; - void (*_sa_sigaction)(int, struct siginfo*, void*); - } _u; - sigset_t sa_mask; int sa_flags; void (*sa_restorer)(void); + sigset64_t sa_mask; }; #endif -// TODO: sigaction contains a sigset_t that's too small on LP32. int sigaction(int __signal, const struct sigaction* __new_action, struct sigaction* __old_action); +int sigaction64(int __signal, const struct sigaction64* __new_action, struct sigaction64* __old_action) __INTRODUCED_IN(28); int siginterrupt(int __signal, int __flag); @@ -191,4 +214,4 @@ __END_DECLS #include <android/legacy_signal_inlines.h> -#endif /* _SIGNAL_H_ */ +#endif diff --git a/libc/libc.arm.map b/libc/libc.arm.map index c345ba636..839c40651 100644 --- a/libc/libc.arm.map +++ b/libc/libc.arm.map @@ -1386,6 +1386,7 @@ LIBC_P { # introduced=P sethostent; setnetent; setprotoent; + sigaction64; sigaddset64; sigdelset64; sigemptyset64; diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map index 3af0d423b..a39a2334a 100644 --- a/libc/libc.arm64.map +++ b/libc/libc.arm64.map @@ -1306,6 +1306,7 @@ LIBC_P { # introduced=P sethostent; setnetent; setprotoent; + sigaction64; sigaddset64; sigdelset64; sigemptyset64; diff --git a/libc/libc.map.txt b/libc/libc.map.txt index 5c54ba105..b3bfa8a8f 100644 --- a/libc/libc.map.txt +++ b/libc/libc.map.txt @@ -1411,6 +1411,7 @@ LIBC_P { # introduced=P sethostent; setnetent; setprotoent; + sigaction64; sigaddset64; sigdelset64; sigemptyset64; diff --git a/libc/libc.mips.map b/libc/libc.mips.map index c3646085d..2a9313228 100644 --- a/libc/libc.mips.map +++ b/libc/libc.mips.map @@ -1370,6 +1370,7 @@ LIBC_P { # introduced=P sethostent; setnetent; setprotoent; + sigaction64; sigaddset64; sigdelset64; sigemptyset64; diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map index 3af0d423b..a39a2334a 100644 --- a/libc/libc.mips64.map +++ b/libc/libc.mips64.map @@ -1306,6 +1306,7 @@ LIBC_P { # introduced=P sethostent; setnetent; setprotoent; + sigaction64; sigaddset64; sigdelset64; sigemptyset64; diff --git a/libc/libc.x86.map b/libc/libc.x86.map index eec2c19cb..d2e73995e 100644 --- a/libc/libc.x86.map +++ b/libc/libc.x86.map @@ -1368,6 +1368,7 @@ LIBC_P { # introduced=P sethostent; setnetent; setprotoent; + sigaction64; sigaddset64; sigdelset64; sigemptyset64; diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map index 3af0d423b..a39a2334a 100644 --- a/libc/libc.x86_64.map +++ b/libc/libc.x86_64.map @@ -1306,6 +1306,7 @@ LIBC_P { # introduced=P sethostent; setnetent; setprotoent; + sigaction64; sigaddset64; sigdelset64; sigemptyset64; diff --git a/libc/malloc_debug/BacktraceData.cpp b/libc/malloc_debug/BacktraceData.cpp index d59728040..57d8f2afe 100644 --- a/libc/malloc_debug/BacktraceData.cpp +++ b/libc/malloc_debug/BacktraceData.cpp @@ -59,13 +59,10 @@ BacktraceData::BacktraceData(DebugData* debug_data, const Config& config, size_t bool BacktraceData::Initialize(const Config& config) { enabled_ = config.backtrace_enabled(); if (config.backtrace_enable_on_signal()) { - struct sigaction enable_act; - memset(&enable_act, 0, sizeof(enable_act)); - + struct sigaction64 enable_act = {}; enable_act.sa_sigaction = ToggleBacktraceEnable; enable_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; - sigemptyset(&enable_act.sa_mask); - if (sigaction(config.backtrace_signal(), &enable_act, nullptr) != 0) { + if (sigaction64(config.backtrace_signal(), &enable_act, nullptr) != 0) { error_log("Unable to set up backtrace signal enable function: %s", strerror(errno)); return false; } @@ -73,13 +70,10 @@ bool BacktraceData::Initialize(const Config& config) { config.backtrace_signal(), getpid()); } - struct sigaction act; - memset(&act, 0, sizeof(act)); - + struct sigaction64 act = {}; act.sa_sigaction = EnableDump; act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; - sigemptyset(&act.sa_mask); - if (sigaction(config.backtrace_dump_signal(), &act, nullptr) != 0) { + if (sigaction64(config.backtrace_dump_signal(), &act, nullptr) != 0) { error_log("Unable to set up backtrace dump signal function: %s", strerror(errno)); return false; } diff --git a/libc/malloc_debug/RecordData.cpp b/libc/malloc_debug/RecordData.cpp index 5a68deb10..55d99438d 100644 --- a/libc/malloc_debug/RecordData.cpp +++ b/libc/malloc_debug/RecordData.cpp @@ -179,13 +179,10 @@ RecordData::RecordData() { } bool RecordData::Initialize(const Config& config) { - struct sigaction dump_act; - memset(&dump_act, 0, sizeof(dump_act)); - + struct sigaction64 dump_act = {}; dump_act.sa_sigaction = RecordDump; dump_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; - sigemptyset(&dump_act.sa_mask); - if (sigaction(config.record_allocs_signal(), &dump_act, nullptr) != 0) { + if (sigaction64(config.record_allocs_signal(), &dump_act, nullptr) != 0) { error_log("Unable to set up record dump signal function: %s", strerror(errno)); return false; } |