Fix security-manager-tests sometimes hanging 20/319920/2
authorKrzysztof Malysa <k.malysa@samsung.com>
Wed, 19 Feb 2025 16:40:34 +0000 (17:40 +0100)
committerKrzysztof Malysa <k.malysa@samsung.com>
Wed, 19 Feb 2025 16:47:42 +0000 (17:47 +0100)
Even security-manager-tests --list sometimes hung.

There were 2 problems:
1. Reading from socket was unchecked for read() returing 0 (indicating
   that the socket was closed on the other end) and this resulted in an
   infinite loop calling read() that always returned 0.
2. The socked was closed because it lived in the parent process that
   already died. Even though the child process requests getting SIGKILL
   on parent death with prctl(PR_SET_PDEATHSIG) it was possible that
   parent died before prctl() succeeded causing the program to misbehave
   in the ways descibed above.

Change-Id: Ief50e9addf4ead899c29f5f28faa0dfd95ab3c84

src/common/temp_test_user.cpp

index c460f0fca4f55082af996f96747bff24bd3cddd9..a1343f97d2c04e9b87497a849c5cb7ef5569b900 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 
+#include <exception>
 #include <memory.h>
 #include <tests_common.h>
 #include <temp_test_user.h>
@@ -95,6 +96,7 @@ TemporaryTestUser::GumdRunner::GumdRunner()
     int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
     RUNNER_ASSERT_MSG(ret != -1, "socketpair() failed");
 
+    pid_t parent_pid = getpid();
     pid_t pid = fork();
     RUNNER_ASSERT_MSG(pid != -1, "fork() failed");
     if (pid) { // parent
@@ -105,6 +107,9 @@ TemporaryTestUser::GumdRunner::GumdRunner()
         m_sock = sock[1];
         close(sock[0]);
         prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // Don't outlive parent process
+        // If the parent died before prctl(), we won't be SIGKILLed
+        if (parent_pid != getppid())
+            std::terminate();
         run(); // Never returns
     }
 }
@@ -206,6 +211,8 @@ void TemporaryTestUser::GumdRunner::get(void *buf, size_t cnt)
         ret = TEMP_FAILURE_RETRY(
             read(m_sock, static_cast<char *>(buf) + pos, cnt - pos));
         RUNNER_ASSERT_MSG(ret != -1, "read() failed");
+        RUNNER_ASSERT_MSG(ret > 0, "expected " << cnt << " bytes, but read only " << pos
+                                   << " and the socket closed");
     }
 }