common: Add replacing fork/exec() to posix_spawn() 07/323507/2
authorYunhee Seo <yuni.seo@samsung.com>
Tue, 29 Apr 2025 05:48:02 +0000 (14:48 +0900)
committerYunhee Seo <yuni.seo@samsung.com>
Tue, 29 Apr 2025 11:55:47 +0000 (20:55 +0900)
As applying unified-system-service,
there was an issue about fork/exec operation in the thread.
Actually, forking() in the thread is undefined behavior.
Thus if the storaged started as a unified-system-service,
fork operation should be replaced to posix_spawn() which is
safer method.
It will ignore parents(thread) signal setting and operated.

Change-Id: I9630335e6c6f0cf5dcf8705066181d6b0b30e305
Signed-off-by: Yunhee Seo <yuni.seo@samsung.com>
CMakeLists.txt
packaging/storaged.spec
src/shared/common.c

index 6577dd966a3f0ea3fe7d51ed5ff96d575e740810..0ec484f7ef32a50d7eb3620b98b445e52d233c83 100644 (file)
@@ -41,7 +41,7 @@ FOREACH(flag ${${PROJECT_NAME}_pkgs_CFLAGS})
 ENDFOREACH(flag)
 
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Werror -rdynamic -Wno-deprecated-declarations")
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions -DUNIFIED_SYSTEM_SERVICE_ENABLED=${UNIFIED_SYSTEM_SERVICE_ON}")
 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -lrt -fPIE")
 SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie")
 # To apply Armoring(Full RELRO), which means GOT Table becomes read-only.
index d0d0e5a4eabcdcae558348180277c45c5a57df0e..b906a92214d2b633db7537b73b1fe5610ee48bbc 100644 (file)
@@ -1,6 +1,7 @@
 #These options are DEACTIVATED by default.
 %bcond_with emulator
 %define extended_storage 0
+%define unified_system_service_on 0
 
 Name:       storaged
 Summary:    Storaged
@@ -110,6 +111,7 @@ This package can be installed optional for auto dbus test.
        -DBLOCK_TMPFS=on \
        -DSTORAGE_MODULE=on \
        -DEXTENDED_STORAGE=%{extended_storage} \
+       -DUNIFIED_SYSTEM_SERVICE_ON=%{unified_system_service_on} \
        -DCRITICAL_LOG_MODULE=on \
        #eol
 
index 225cd021c86c320fb00cdc1c602696dc3d5e70b4..61614182d77293bc9d76f4ab554ed366fbf70079 100644 (file)
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 #include <stdbool.h>
 #include <unistd.h>
+#include <spawn.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
@@ -45,6 +46,8 @@
 #define MODEL_NAME      "http://tizen.org/system/model_name"
 #define MODEL_EMULATOR  "Emulator"
 
+static int g_unified_system_service_on = UNIFIED_SYSTEM_SERVICE_ENABLED;
+
 static const char *rm_arg[] = {
        "/usr/bin/rm",
        "-rf", NULL, NULL,
@@ -107,7 +110,7 @@ static void child(int argc, const char *argv[])
                exit(EXIT_FAILURE);
 }
 
-int run_child(int argc, const char *argv[])
+int run_fork(int argc, const char *argv[])
 {
        pid_t pid;
        struct sigaction act, oldact;
@@ -148,6 +151,57 @@ int run_child(int argc, const char *argv[])
        return r;
 }
 
+int run_posix_spawn(int argc, const char *argv[])
+{
+       pid_t pid;
+       int status;
+       int r = 0;
+       FILE *fp;
+       posix_spawnattr_t attr;
+       sigset_t sigmask;
+       sigset_t sigdefault;
+
+       if (!argv)
+               return -EINVAL;
+
+       fp = fopen(argv[0], "r");
+       if (fp == NULL) {
+               _E("Failed to %s: %d", argv[0], errno);
+               return -errno;
+       }
+       fclose(fp);
+
+       posix_spawnattr_init(&attr);
+       sigemptyset(&sigmask);
+       sigemptyset(&sigdefault);
+       sigprocmask(SIG_BLOCK, &sigmask, NULL);
+
+       posix_spawnattr_setsigmask(&attr, &sigmask);
+       posix_spawnattr_setsigdefault(&attr, &sigdefault);
+       posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSIGDEF);
+
+       r = posix_spawn(&pid, argv[0], NULL, &attr, (char**)argv, NULL);
+       if (r != 0)
+               _E("Failed to posix_spawn: %d", r);
+
+       waitpid(pid, &status, 0);
+       _I("Process(%d) terminated by exit(%d).", pid, WEXITSTATUS(status));
+
+       r = posix_spawnattr_destroy(&attr);
+       if (r != 0)
+               _E("Failed to posix_spawnattr_destroy: %d", r);
+
+       return r;
+}
+
+int run_child(int argc, const char *argv[])
+{
+       if (g_unified_system_service_on)
+               return run_posix_spawn(argc, argv);
+       else
+               return run_fork(argc, argv);
+}
+
 int remove_directory(const char*path)
 {
        int argc;