Skip to content

Commit

Permalink
enable important signals in master initialization (#931)
Browse files Browse the repository at this point in the history
Enable SIGBUS, SIGFPE, SIGILL and SIGSEGV on master initialization
Also fix sigsegv in regex initialization and add tests
  • Loading branch information
astrophysik authored Nov 3, 2023
1 parent 8ae1454 commit 443616c
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 10 deletions.
23 changes: 19 additions & 4 deletions common/dl-utils-lite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <unistd.h>
#include <dirent.h>

#include "common/server/crash-dump.h"
#include "common/stats/provider.h"
#include "common/wrappers/pathname.h"

Expand Down Expand Up @@ -147,6 +148,15 @@ void dl_restore_signal_mask () {
void dl_block_all_signals () {
sigset_t mask;
sigfillset (&mask);
// According linux man sigprocmask page
// if SIGBUS, SIGFPE, SIGILL, or SIGSEGV are generated while they are blocked, the result is undefined,
// unless the signal was generated by kill(2), sigqueue(3), or raise(3).
sigdelset(&mask, SIGSEGV);
sigdelset(&mask, SIGBUS);
sigdelset(&mask, SIGFPE);
sigdelset(&mask, SIGILL);
// Allow SIGQUIT to generate coredump in signal handlers
sigdelset(&mask, SIGQUIT);
int err = sigprocmask (SIG_SETMASK, &mask, &old_mask);
old_mask_inited = 1;
dl_passert (err != -1, "failed to block all signals");
Expand All @@ -160,16 +170,21 @@ void dl_allow_all_signals () {
dl_passert (err != -1, "failed to allow all signals");
}

static void runtime_handler (const int sig) {
fprintf (stderr, "%s caught, terminating program\n", sig == SIGSEGV ? "SIGSEGV" : "SIGABRT");
static void runtime_handler (const int sig, siginfo_t *info __attribute__((unused)), void *ucontext) {
fprintf (stderr, "%s caught, terminating program\n", strsignal(sig));
crash_dump_write(static_cast<ucontext_t *>(ucontext));
dl_print_backtrace();
dl_print_backtrace_gdb();
raise(SIGQUIT);
_exit (EXIT_FAILURE);
}

void dl_set_default_handlers () {
dl_signal (SIGSEGV, runtime_handler);
dl_signal (SIGABRT, runtime_handler);
dl_sigaction(SIGSEGV, nullptr, dl_get_empty_sigset(), SA_SIGINFO | SA_ONSTACK | SA_RESTART, runtime_handler);
dl_sigaction(SIGBUS, nullptr, dl_get_empty_sigset(), SA_SIGINFO | SA_ONSTACK | SA_RESTART, runtime_handler);
dl_sigaction(SIGFPE, nullptr, dl_get_empty_sigset(), SA_SIGINFO | SA_ONSTACK | SA_RESTART, runtime_handler);
dl_sigaction(SIGILL, nullptr, dl_get_empty_sigset(), SA_SIGINFO | SA_ONSTACK | SA_RESTART, runtime_handler);
dl_sigaction(SIGABRT, nullptr, dl_get_empty_sigset(), SA_SIGINFO | SA_ONSTACK | SA_RESTART, runtime_handler);
}

char *dl_pstr (char const *msg, ...) {
Expand Down
3 changes: 2 additions & 1 deletion runtime/datetime/timelib_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "common/containers/final_action.h"
#include "common/smart_ptrs/singleton.h"
#include "server/php-engine-vars.h"

// these constants are a part of the private timelib API, but PHP uses them internally;
// we define them here locally
Expand Down Expand Up @@ -214,7 +215,7 @@ std::pair<int64_t, bool> php_timelib_strtotime(const string &tz_name, const stri
return {0, false};
}

bool use_heap_memory = (dl::get_script_memory_stats().memory_limit == 0);
bool use_heap_memory = (process_type == ProcessType::master);
auto malloc_replacement_guard = make_malloc_replacement_with_script_allocator(!use_heap_memory);

timelib_time *now = timelib_time_ctor();
Expand Down
7 changes: 4 additions & 3 deletions runtime/regexp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "common/unicode/utf8-utils.h"

#include "runtime/critical_section.h"
#include "server/php-engine-vars.h"

int64_t preg_replace_count_dummy;

Expand Down Expand Up @@ -314,7 +315,7 @@ void regexp::init(const string &regexp_string, const char *function, const char
static array<regexp *> *regexp_cache = (array<regexp *> *)regexp_cache_storage;
static long long regexp_last_query_num = -1;

use_heap_memory = (dl::get_script_memory_stats().memory_limit == 0);
use_heap_memory = (process_type == ProcessType::master);

if (!use_heap_memory) {
if (dl::query_num != regexp_last_query_num) {
Expand Down Expand Up @@ -411,7 +412,7 @@ void regexp::init(const char *regexp_string, int64_t regexp_len, const char *fun

static_SB.clean().append(regexp_string + 1, static_cast<size_t>(regexp_end - 1));

use_heap_memory = (dl::get_script_memory_stats().memory_limit == 0);
use_heap_memory = (process_type == ProcessType::master);

auto malloc_replacement_guard = make_malloc_replacement_with_script_allocator(!use_heap_memory);

Expand Down Expand Up @@ -590,7 +591,7 @@ void regexp::clean() {
subpatterns_count = 0;
named_subpatterns_count = 0;
is_utf8 = false;
use_heap_memory = false;
use_heap_memory = (process_type == ProcessType::master);

if (pcre_regexp != nullptr) {
pcre_free(pcre_regexp);
Expand Down
3 changes: 1 addition & 2 deletions server/php-engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2322,8 +2322,6 @@ void init_default() {
kprintf ("fatal: not enough workers for general purposes\n");
exit(1);
}

dl_set_default_handlers();
now = (int)time(nullptr);

pid = getpid();
Expand Down Expand Up @@ -2365,6 +2363,7 @@ void init_default() {

int run_main(int argc, char **argv, php_mode mode) {
init_version_string(NAME_VERSION);
dl_set_default_handlers();
dl_block_all_signals();
#if !ASAN_ENABLED
set_core_dump_rlimit(1LL << 40);
Expand Down
6 changes: 6 additions & 0 deletions tests/phpt/regexp/008_preg_errors.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
@ok
<?php

function test_static_preg_errors() {
var_dump(preg_match('[ \(\)+-]/', 'simple', $matches));
var_dump(preg_match('[\]sigsegv', 'simple', $matches));
}

function test_preg_errors_constants() {
var_dump(PREG_NO_ERROR);
var_dump(PREG_INTERNAL_ERROR);
Expand Down Expand Up @@ -66,6 +71,7 @@ function test_preg_errors_offset() {
var_dump(preg_last_error() == PREG_BAD_UTF8_ERROR);
}

test_static_preg_errors();
test_preg_errors_constants();
test_preg_errors();
test_preg_errors_offset();

0 comments on commit 443616c

Please sign in to comment.