Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

posix: block SIGPIPE in all threads #1030

Merged
merged 1 commit into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/android/jni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include "config/config.hpp"
#include "crypto/crypter_export.hpp"

#include <pthread.h>
#include <signal.h>
#include <string>
#include <vector>

Expand All @@ -18,6 +20,20 @@ jobject g_activity_obj = nullptr;
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
g_jvm = vm;

// setup signal handler
signal(SIGPIPE, SIG_IGN);

/* Block SIGPIPE in all threads, this can happen if a thread calls write on
a closed pipe. */
sigset_t sigpipe_mask;
sigemptyset(&sigpipe_mask);
sigaddset(&sigpipe_mask, SIGPIPE);
sigset_t saved_mask;
if (pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &saved_mask) == -1) {
perror("pthread_sigmask failed");
return -1;
}

return JNI_VERSION_1_6;
}

Expand Down
19 changes: 15 additions & 4 deletions src/cli/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,21 @@ static asio::ip::tcp::resolver::results_type ResolveAddress(const std::string& d
}

int main(int argc, const char* argv[]) {
#ifndef _WIN32
// setup signal handler
signal(SIGPIPE, SIG_IGN);

/* Block SIGPIPE in all threads, this can happen if a thread calls write on
a closed pipe. */
sigset_t sigpipe_mask;
sigemptyset(&sigpipe_mask);
sigaddset(&sigpipe_mask, SIGPIPE);
sigset_t saved_mask;
if (pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &saved_mask) == -1) {
perror("pthread_sigmask failed");
return -1;
}
#endif
SetExecutablePath(argv[0]);
std::string exec_path;
if (!GetExecutablePath(&exec_path)) {
Expand Down Expand Up @@ -206,10 +221,6 @@ int main(int argc, const char* argv[]) {
};
signals.async_wait(cb);

#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_OHOS)
CHECK_NE(SIG_ERR, signal(SIGPIPE, SIG_IGN));
#endif

io_context.run();

PrintMallocStats();
Expand Down
24 changes: 19 additions & 5 deletions src/cli/cli_worker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
#include <absl/flags/flag.h>
#include <absl/strings/str_cat.h>
#include <absl/strings/str_join.h>
#include <signal.h>
#include "third_party/boringssl/src/include/openssl/crypto.h"

#ifdef _WIN32
#include <ws2tcpip.h>
#else
#include <pthread.h>
#include <signal.h>
#endif

#include "cli/cli_server.hpp"
Expand Down Expand Up @@ -41,10 +43,6 @@ Worker::Worker()

CRYPTO_library_init();

#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_OHOS)
CHECK_NE(SIG_ERR, signal(SIGPIPE, SIG_IGN));
#endif

thread_ = std::make_unique<std::thread>([this] { WorkFunc(); });
}

Expand Down Expand Up @@ -173,6 +171,22 @@ void Worker::WorkFunc() {
}

LOG(INFO) << "worker: background thread started";

#ifndef _WIN32
/* Check if we have blocked SIGPIPE in all threads, this can happen if a thread calls write on
a closed pipe. */
sigset_t saved_mask;
if (pthread_sigmask(SIG_BLOCK, nullptr, &saved_mask) == 0) {
if (sigismember(&saved_mask, SIGPIPE)) {
LOG(INFO) << "worker: signal SIGPIPE is masked as BLOCKED";
} else {
PLOG(WARNING) << "worker: signal SIGPIPE is not masked as BLOCKED!";
}
} else {
PLOG(WARNING) << "worker: pthread_sigmask failed";
}
#endif

while (!in_destroy_) {
work_guard_ =
std::make_unique<asio::executor_work_guard<asio::io_context::executor_type>>(io_context_.get_executor());
Expand Down
15 changes: 15 additions & 0 deletions src/gtk/yass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,21 @@ static const char* kAppId = "it.gui.yass";
static const char* kAppName = YASS_APP_PRODUCT_NAME;

int main(int argc, const char** argv) {
#ifndef _WIN32
// setup signal handler
signal(SIGPIPE, SIG_IGN);

/* Block SIGPIPE in all threads, this can happen if a thread calls write on
a closed pipe. */
sigset_t sigpipe_mask;
sigemptyset(&sigpipe_mask);
sigaddset(&sigpipe_mask, SIGPIPE);
sigset_t saved_mask;
if (pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &saved_mask) == -1) {
perror("pthread_sigmask failed");
return -1;
}
#endif
SetExecutablePath(argv[0]);
std::string exec_path;
if (!GetExecutablePath(&exec_path)) {
Expand Down
15 changes: 15 additions & 0 deletions src/gtk4/yass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,21 @@ YASSGtkApp* yass_app_new(void) {
} // extern "C"

int main(int argc, const char** argv) {
#ifndef _WIN32
// setup signal handler
signal(SIGPIPE, SIG_IGN);

/* Block SIGPIPE in all threads, this can happen if a thread calls write on
a closed pipe. */
sigset_t sigpipe_mask;
sigemptyset(&sigpipe_mask);
sigaddset(&sigpipe_mask, SIGPIPE);
sigset_t saved_mask;
if (pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &saved_mask) == -1) {
perror("pthread_sigmask failed");
return -1;
}
#endif
SetExecutablePath(argv[0]);
std::string exec_path;
if (!GetExecutablePath(&exec_path)) {
Expand Down
16 changes: 16 additions & 0 deletions src/harmony/yass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include <js_native_api_types.h>
#include <napi/native_api.h>

#include <pthread.h>
#include <signal.h>
#include <unistd.h>
#include <memory>
#include <thread>
Expand Down Expand Up @@ -1153,6 +1155,20 @@ static napi_module yassModule = {
};

extern "C" __attribute__((constructor)) void RegisterEntryModule(void) {
// setup signal handler
signal(SIGPIPE, SIG_IGN);

/* Block SIGPIPE in all threads, this can happen if a thread calls write on
a closed pipe. */
sigset_t sigpipe_mask;
sigemptyset(&sigpipe_mask);
sigaddset(&sigpipe_mask, SIGPIPE);
sigset_t saved_mask;
if (pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &saved_mask) == -1) {
perror("pthread_sigmask failed");
return -1;
}

napi_module_register(&yassModule);
}

Expand Down
18 changes: 18 additions & 0 deletions src/ios/extensions/YassPacketTunnelProvider.mm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#import "YassPacketTunnelProvider.h"

#include <pthread.h>
#include <signal.h>
#include <atomic>
#include <thread>

Expand Down Expand Up @@ -34,6 +36,22 @@ @implementation YassPacketTunnelProvider {

- (void)startTunnelWithOptions:(NSDictionary*)options completionHandler:(void (^)(NSError*))completionHandler {
stopped_ = false;
// setup signal handler
signal(SIGPIPE, SIG_IGN);

/* Block SIGPIPE in all threads, this can happen if a thread calls write on
a closed pipe. */
sigset_t sigpipe_mask;
sigemptyset(&sigpipe_mask);
sigaddset(&sigpipe_mask, SIGPIPE);
sigset_t saved_mask;
if (pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &saved_mask) == -1) {
perror("pthread_sigmask failed");
completionHandler([NSError errorWithDomain:@"it.gui.ios.yass"
code:200
userInfo:@{@"Error reason" : @(strerror(errno))}]);
return;
}
SetExecutablePath("UNKNOWN.ext");

NETunnelProviderProtocol* protocolConfiguration = (NETunnelProviderProtocol*)self.protocolConfiguration;
Expand Down
15 changes: 15 additions & 0 deletions src/ios/main.mm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#include <locale.h>
#include <mach-o/dyld.h>
#include <pthread.h>
#include <signal.h>
#include <stdexcept>
#include <string>

Expand All @@ -26,6 +28,19 @@
const ProgramType pType = YASS_CLIENT_SLAVE;

int main(int argc, const char** argv) {
// setup signal handler
signal(SIGPIPE, SIG_IGN);

/* Block SIGPIPE in all threads, this can happen if a thread calls write on
a closed pipe. */
sigset_t sigpipe_mask;
sigemptyset(&sigpipe_mask);
sigaddset(&sigpipe_mask, SIGPIPE);
sigset_t saved_mask;
if (pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &saved_mask) == -1) {
perror("pthread_sigmask failed");
return -1;
}
SetExecutablePath(argv[0]);
std::string exec_path;
if (!GetExecutablePath(&exec_path)) {
Expand Down
16 changes: 16 additions & 0 deletions src/mac/main.mm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#include <locale.h>
#include <mach-o/dyld.h>
#include <pthread.h>
#include <signal.h>
#include <stdexcept>
#include <string>

Expand Down Expand Up @@ -37,6 +39,20 @@
#endif

int main(int argc, const char** argv) {
// setup signal handler
signal(SIGPIPE, SIG_IGN);

/* Block SIGPIPE in all threads, this can happen if a thread calls write on
a closed pipe. */
sigset_t sigpipe_mask;
sigemptyset(&sigpipe_mask);
sigaddset(&sigpipe_mask, SIGPIPE);
sigset_t saved_mask;
if (pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &saved_mask) == -1) {
perror("pthread_sigmask failed");
return -1;
}

SetExecutablePath(argv[0]);
std::string exec_path;
if (!GetExecutablePath(&exec_path)) {
Expand Down
39 changes: 15 additions & 24 deletions src/qt6/yass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,21 @@
#include "version.h"

int main(int argc, const char** argv) {
#ifndef _WIN32
// setup signal handler
signal(SIGPIPE, SIG_IGN);

/* Block SIGPIPE in all threads, this can happen if a thread calls write on
a closed pipe. */
sigset_t sigpipe_mask;
sigemptyset(&sigpipe_mask);
sigaddset(&sigpipe_mask, SIGPIPE);
sigset_t saved_mask;
if (pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &saved_mask) == -1) {
perror("pthread_sigmask failed");
return -1;
}
#endif
SetExecutablePath(argv[0]);
std::string exec_path;
if (!GetExecutablePath(&exec_path)) {
Expand Down Expand Up @@ -59,30 +74,6 @@ int main(int argc, const char** argv) {

YASSApp program(argc, const_cast<char**>(argv));

#ifndef _WIN32
// setup signal handler
signal(SIGPIPE, SIG_IGN);

struct sigaction sig_handler;

sig_handler.sa_handler = [](int signal_num) { App()->quit(); };
sigemptyset(&sig_handler.sa_mask);
sig_handler.sa_flags = 0;

sigaction(SIGINT, &sig_handler, nullptr);

/* Block SIGPIPE in all threads, this can happen if a thread calls write on
a closed pipe. */
sigset_t sigpipe_mask;
sigemptyset(&sigpipe_mask);
sigaddset(&sigpipe_mask, SIGPIPE);
sigset_t saved_mask;
if (pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &saved_mask) == -1) {
PLOG(WARNING) << "pthread_sigmask failed";
return -1;
}
#endif

// call program init
if (!program.Init()) {
return 0;
Expand Down
19 changes: 15 additions & 4 deletions src/server/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,21 @@ const ProgramType pType = YASS_SERVER;
using namespace net::server;

int main(int argc, const char* argv[]) {
#ifndef _WIN32
// setup signal handler
signal(SIGPIPE, SIG_IGN);

/* Block SIGPIPE in all threads, this can happen if a thread calls write on
a closed pipe. */
sigset_t sigpipe_mask;
sigemptyset(&sigpipe_mask);
sigaddset(&sigpipe_mask, SIGPIPE);
sigset_t saved_mask;
if (pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &saved_mask) == -1) {
perror("pthread_sigmask failed");
return -1;
}
#endif
SetExecutablePath(argv[0]);
std::string exec_path;
if (!GetExecutablePath(&exec_path)) {
Expand Down Expand Up @@ -176,10 +191,6 @@ int main(int argc, const char* argv[]) {
};
signals.async_wait(cb);

#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID)
CHECK_NE(SIG_ERR, signal(SIGPIPE, SIG_IGN));
#endif

#ifndef _WIN32
// change user and change group
std::string username = absl::GetFlag(FLAGS_user);
Expand Down
19 changes: 15 additions & 4 deletions src/ss_benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,21 @@ int xc_main() {
char* argv[] = {(char*)"xc_main", nullptr};
#else
int main(int argc, char** argv) {
#endif
#ifndef _WIN32
// setup signal handler
signal(SIGPIPE, SIG_IGN);

/* Block SIGPIPE in all threads, this can happen if a thread calls write on
a closed pipe. */
sigset_t sigpipe_mask;
sigemptyset(&sigpipe_mask);
sigaddset(&sigpipe_mask, SIGPIPE);
sigset_t saved_mask;
if (pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &saved_mask) == -1) {
perror("pthread_sigmask failed");
return -1;
}
#endif
SetExecutablePath(argv[0]);
std::string exec_path;
Expand Down Expand Up @@ -631,10 +646,6 @@ int main(int argc, char** argv) {

CRYPTO_library_init();

#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_OHOS)
CHECK_NE(SIG_ERR, signal(SIGPIPE, SIG_IGN));
#endif

if (absl::GetFlag(FLAGS_ipv6_mode)) {
CHECK(Net_ipv6works()) << "IPv6 stack is required but not available";
}
Expand Down
Loading
Loading