} while (true);
}
+static void sig_handler(int signo)
+{
+ (void)signo;
+ std::atomic_thread_fence(std::memory_order_acquire);
+ int tid = Syscall::gettid();
+ set_tid_state(tid, 1);
+ while(g_th_barrier == 0)
+ usleep(SLEEP_CONST);
+ if (g_p_app_label)
+ if (label_for_self_internal(tid) != 0)
+ return;
+ if (cap_set_proc(g_cap))
+ return;
+ set_tid_state(tid, 2);
+ while(g_th_barrier == 1)
+ usleep(SLEEP_CONST);
+}
+
static inline int security_manager_sync_threads_internal(const std::string &app_label)
{
static_assert(ATOMIC_INT_LOCK_FREE == 2, "std::atomic<int> is not always lock free");
sigemptyset(&act.sa_mask);
act.sa_flags = SA_RESTART;
- act.sa_handler = [](int signo) {
- (void)signo;
- std::atomic_thread_fence(std::memory_order_acquire);
- int tid = Syscall::gettid();
- set_tid_state(tid, 1);
- while(g_th_barrier == 0)
- usleep(SLEEP_CONST);
- if (g_p_app_label)
- if (label_for_self_internal(tid) != 0)
- return;
- if (cap_set_proc(g_cap))
- return;
- set_tid_state(tid, 2);
- while(g_th_barrier == 1)
- usleep(SLEEP_CONST);
- };
+ act.sa_handler = sig_handler;
if (Syscall::sigaction(SIGSETXID, &act, &old) < 0) {
LogError("Error in sigaction()");
initialize_tid_states();
std::atomic_thread_fence(std::memory_order_release);
+ // It seems possible that lazy binding of the SO symbols loaded by linker can cause problems
+ // when the SIGSETXID arrives in some thread at the precise moment that a symbol in a thread
+ // is being lazy-initialized. By doing calls below we're ensuring that symbols used inside
+ // our handler are already loaded.
+ // not calling open/read/write/close/std::string anywyere as these are already used before,
+ // including openning connection to the daemon that uses sockets.
+ // <begin of calling functions to load symbols>
+ (void)syscall(-1);
+ usleep(SLEEP_CONST);
+ char buffer [10];
+ int a = 1;
+ (void)sprintf(buffer, "%d", a);
+ cap_t tmp_cap = cap_get_proc();
+ if (!tmp_cap) {
+ LogError("Unable to allocate capability object");
+ return SECURITY_MANAGER_ERROR_MEMORY;
+ }
+ (void)cap_set_proc(tmp_cap);
+ (void)cap_free(tmp_cap);
+ // <end of calling functions just to load them>
+
g_th_barrier = 0;
auto enabled = SecurityManager::Log::LogSystemSingleton::Instance().IsLoggingEnabled();