Change the signal used by security-manager prepare_app implementation 45/295445/7
authorTomasz Swierczek <t.swierczek@samsung.com>
Fri, 7 Jul 2023 08:10:20 +0000 (10:10 +0200)
committerTomasz Swierczek <t.swierczek@samsung.com>
Mon, 10 Jul 2023 15:26:28 +0000 (15:26 +0000)
SIGSETXID was used previously to mimic the exact behaviour of glibc.

However, in testing on VD side using SIGSETXID can cause interference
with regular glibc usage, which also leads to abort().

To give more details: if threads are so delayed that their signal handling
is done ie. > 2 seconds after the sending was done, the signal arrives
in the thread when security-manager already did change the signal handler
back to original glibc. Then, glibc, checks whether it sent the signal,
it recognizes it didn't, and aborts/quits.

Changing signal number will not cause glibc to abort/fail, and if execution
gets back to security-manager main thread, IT will fail, printing
all necessary information about threads for debugging, before calling abort().

Changed signal number to SIGRTMIN+2, as advised.

Change-Id: I9b755504898daee71997ee35023c3d647e332b84

src/client/client-security-manager.cpp

index 62a7bdca01db44ca072ba7acb186f32c98ac337f..316c3ad525295568a057afac839864c6cd455a01 100644 (file)
@@ -111,8 +111,10 @@ static int g_all_tid_num;
 
 #define MAX_SIG_WAIT_TIME   1000
 
-// Hackish, based on glibc's definition in sysdeps/unix/sysv/linux/nptl-signals.h
-#define SIGSETXID           (__SIGRTMIN + 1)
+// Hackish, but decided NOT to use signal SIGSETXID used by glibc
+// as this was proven to cause interference with app candidate
+// processes using glibc at the time of security-manager operation
+#define SIGNAL_NUM           (__SIGRTMIN + 2)
 
 SECURITY_MANAGER_API
 const char *security_manager_strerror(enum lib_retcode rc)
@@ -676,7 +678,7 @@ static inline int security_manager_sync_threads_internal(const std::string &app_
             g_threads_count--;
         };
 
-        if (Syscall::sigaction(SIGSETXID, &act, &old) < 0) {
+        if (Syscall::sigaction(SIGNAL_NUM, &act, &old) < 0) {
             LogError("Error in sigaction()");
             return SECURITY_MANAGER_ERROR_UNKNOWN;
         }
@@ -693,7 +695,7 @@ static inline int security_manager_sync_threads_internal(const std::string &app_
             synced_tids.push_back(tid); // this will not add current TID (but its already added)
             g_tid_status[tid_index++].tid = tid;
 
-            if (Syscall::tgkill(cur_pid, tid, SIGSETXID) < 0) {
+            if (Syscall::tgkill(cur_pid, tid, SIGNAL_NUM) < 0) {
                 const auto err = errno;
                 if (ESRCH == err) { // thread already gone
                     threads_gone++;
@@ -711,7 +713,7 @@ static inline int security_manager_sync_threads_internal(const std::string &app_
         for (int i = MAX_SIG_WAIT_TIME; g_threads_count && i; i--)
             usleep(2000);   // 2 ms
 
-        Syscall::sigaction(SIGSETXID, &old, nullptr);
+        Syscall::sigaction(SIGNAL_NUM, &old, nullptr);
 
         if (g_threads_count) {
             LogError("Not all threads synchronized: threads left: " << g_threads_count);