fix(userspace): replace strerror() with thread-safe strerror_r()

strerror() returns a pointer to a shared static buffer, making it
unsafe when called concurrently from different threads. Replace all
call sites with strerror_r() using stack-local buffers, consistent
with the existing pattern in create_signal_handlers.cpp.

Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
This commit is contained in:
Leonardo Grasso
2026-04-09 11:41:37 +02:00
parent bb96f26fce
commit 26daebb1a9
4 changed files with 32 additions and 13 deletions

View File

@@ -36,10 +36,13 @@ falco::app::run_result falco::app::actions::print_kernel_version(const falco::ap
std::ifstream input_file("/proc/version");
if(!input_file.is_open()) {
// We don't want to fail, we just need to log something
falco_logger::log(
falco_logger::level::INFO,
"Cannot read under '/proc/version' (err_message: '" + std::string(strerror(errno)) +
"', err_code: " + std::to_string(errno) + "). No info provided, go on.");
int saved_errno = errno;
char errbuf[256];
const char* errstr = strerror_r(saved_errno, errbuf, sizeof(errbuf));
falco_logger::log(falco_logger::level::INFO,
"Cannot read under '/proc/version' (err_message: '" +
std::string(errstr) + "', err_code: " +
std::to_string(saved_errno) + "). No info provided, go on.");
return run_result::ok();
}

View File

@@ -95,7 +95,9 @@ falco::app::run_result falco::app::actions::print_support(falco::app::state& s)
nlohmann::json support;
if(get_sysinfo(support) != 0) {
return run_result::fatal(std::string("Could not get system info: ") + strerror(errno));
char errbuf[256];
const char* errstr = strerror_r(errno, errbuf, sizeof(errbuf));
return run_result::fatal(std::string("Could not get system info: ") + errstr);
}
const falco::versions_info infos(s.offline_inspector);

View File

@@ -26,9 +26,11 @@ void falco::outputs::output_program::open_pfile() {
m_pfile = popen(m_oc.options["program"].c_str(), "w");
if(m_pfile == nullptr) {
char errbuf[256];
const char* errstr = strerror_r(errno, errbuf, sizeof(errbuf));
falco_logger::log(falco_logger::level::ERR,
"Failed to open program output: " + m_oc.options["program"] +
" (error: " + std::string(std::strerror(errno)) + ")");
" (error: " + errstr + ")");
return;
}
@@ -38,7 +40,7 @@ void falco::outputs::output_program::open_pfile() {
}
}
void falco::outputs::output_program::output(const message *msg) {
void falco::outputs::output_program::output(const message* msg) {
open_pfile();
if(m_pfile != nullptr) {

View File

@@ -71,7 +71,9 @@ bool stats_writer::init_ticker(uint32_t interval_msec, std::string& err) {
memset(&handler, 0, sizeof(handler));
handler.sa_handler = &timer_handler;
if(sigaction(SIGALRM, &handler, NULL) == -1) {
err = std::string("Could not set up signal handler for periodic timer: ") + strerror(errno);
char errbuf[256];
const char* errstr = strerror_r(errno, errbuf, sizeof(errbuf));
err = std::string("Could not set up signal handler for periodic timer: ") + errstr;
return false;
}
@@ -93,7 +95,9 @@ bool stats_writer::init_ticker(uint32_t interval_msec, std::string& err) {
memset(&handler, 0, sizeof(handler));
handler.sa_handler = &timer_handler;
if(sigaction(SIGALRM, &handler, NULL) == -1) {
err = std::string("Could not set up signal handler for periodic timer: ") + strerror(errno);
char errbuf[256];
const char* errstr = strerror_r(errno, errbuf, sizeof(errbuf));
err = std::string("Could not set up signal handler for periodic timer: ") + errstr;
return false;
}
@@ -119,7 +123,9 @@ bool stats_writer::init_ticker(uint32_t interval_msec, std::string& err) {
memset(&handler, 0, sizeof(handler));
handler.sa_handler = &timer_handler;
if(sigaction(SIGALRM, &handler, NULL) == -1) {
err = std::string("Could not set up signal handler for periodic timer: ") + strerror(errno);
char errbuf[256];
const char* errstr = strerror_r(errno, errbuf, sizeof(errbuf));
err = std::string("Could not set up signal handler for periodic timer: ") + errstr;
return false;
}
@@ -131,14 +137,18 @@ bool stats_writer::init_ticker(uint32_t interval_msec, std::string& err) {
// delete any previously set timer
if(s_timerid_exists) {
if(timer_delete(s_timerid) == -1) {
err = std::string("Could not delete previous timer: ") + strerror(errno);
char errbuf[256];
const char* errstr = strerror_r(errno, errbuf, sizeof(errbuf));
err = std::string("Could not delete previous timer: ") + errstr;
return false;
}
s_timerid_exists = false;
}
if(timer_create(CLOCK_MONOTONIC, &sev, &s_timerid) == -1) {
err = std::string("Could not create periodic timer: ") + strerror(errno);
char errbuf[256];
const char* errstr = strerror_r(errno, errbuf, sizeof(errbuf));
err = std::string("Could not create periodic timer: ") + errstr;
return false;
}
s_timerid_exists = true;
@@ -148,7 +158,9 @@ bool stats_writer::init_ticker(uint32_t interval_msec, std::string& err) {
timer.it_interval = timer.it_value;
if(timer_settime(s_timerid, 0, &timer, NULL) == -1) {
err = std::string("Could not set up periodic timer: ") + strerror(errno);
char errbuf[256];
const char* errstr = strerror_r(errno, errbuf, sizeof(errbuf));
err = std::string("Could not set up periodic timer: ") + errstr;
return false;
}