]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
selftests/pidfd: add tests for PIDFD_SELF_*
authorLorenzo Stoakes <lorenzo.stoakes@oracle.com>
Thu, 30 Jan 2025 20:40:30 +0000 (20:40 +0000)
committerChristian Brauner <brauner@kernel.org>
Wed, 5 Feb 2025 14:14:55 +0000 (15:14 +0100)
Add tests to assert that PIDFD_SELF* correctly refers to the current
thread and process.

We explicitly test pidfd_send_signal(), however We defer testing of
mm-specific functionality which uses pidfd, namely process_madvise() and
process_mrelease() to mm testing (though note the latter can not be
sensibly tested as it would require the testing process to be dying).

We also correct the pidfd_open_test.c fields which refer to .request_mask
whereas the UAPI header refers to .mask, which otherwise break the import
of the UAPI header.

Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Link: https://lore.kernel.org/r/7ab0e48b26ba53abf7b703df2dd11a2e99b8efb2.1738268370.git.lorenzo.stoakes@oracle.com
Reviewed-by: Shakeel Butt <shakeel.butt@linux.dev>
Signed-off-by: Christian Brauner <brauner@kernel.org>
tools/testing/selftests/pidfd/pidfd_open_test.c
tools/testing/selftests/pidfd/pidfd_test.c

index ce413a221bacd88006eb9aba201f91a60e71218c..9a40ccb1ff6dc45fb53f6ef0e977658c2059cae5 100644 (file)
@@ -31,7 +31,7 @@
 #define PIDFD_INFO_CGROUPID            (1UL << 0)
 
 struct pidfd_info {
-       __u64 request_mask;
+       __u64 mask;
        __u64 cgroupid;
        __u32 pid;
        __u32 tgid;
@@ -148,7 +148,7 @@ out:
 int main(int argc, char **argv)
 {
        struct pidfd_info info = {
-               .request_mask = PIDFD_INFO_CGROUPID,
+               .mask = PIDFD_INFO_CGROUPID,
        };
        int pidfd = -1, ret = 1;
        pid_t pid;
@@ -227,7 +227,7 @@ int main(int argc, char **argv)
                               getegid(), info.sgid);
                goto on_error;
        }
-       if ((info.request_mask & PIDFD_INFO_CGROUPID) && info.cgroupid == 0) {
+       if ((info.mask & PIDFD_INFO_CGROUPID) && info.cgroupid == 0) {
                ksft_print_msg("cgroupid should not be 0 when PIDFD_INFO_CGROUPID is set\n");
                goto on_error;
        }
index e9728e86b4f25449ad4390b7242880ca27f08e8a..fcd85cad9f18fd2ff8d1721786430c46976d0766 100644 (file)
@@ -42,12 +42,41 @@ static pid_t pidfd_clone(int flags, int *pidfd, int (*fn)(void *))
 #endif
 }
 
-static int signal_received;
+static pthread_t signal_received;
 
 static void set_signal_received_on_sigusr1(int sig)
 {
        if (sig == SIGUSR1)
-               signal_received = 1;
+               signal_received = pthread_self();
+}
+
+static int send_signal(int pidfd)
+{
+       int ret = 0;
+
+       if (sys_pidfd_send_signal(pidfd, SIGUSR1, NULL, 0) < 0) {
+               ret = -EINVAL;
+               goto exit;
+       }
+
+       if (signal_received != pthread_self()) {
+               ret = -EINVAL;
+               goto exit;
+       }
+
+exit:
+       signal_received = 0;
+       return ret;
+}
+
+static void *send_signal_worker(void *arg)
+{
+       int pidfd = (int)(intptr_t)arg;
+       int ret;
+
+       /* We forward any errors for the caller to handle. */
+       ret = send_signal(pidfd);
+       return (void *)(intptr_t)ret;
 }
 
 /*
@@ -56,8 +85,11 @@ static void set_signal_received_on_sigusr1(int sig)
  */
 static int test_pidfd_send_signal_simple_success(void)
 {
-       int pidfd, ret;
+       int pidfd;
        const char *test_name = "pidfd_send_signal send SIGUSR1";
+       pthread_t thread;
+       void *thread_res;
+       int err;
 
        if (!have_pidfd_send_signal) {
                ksft_test_result_skip(
@@ -66,25 +98,45 @@ static int test_pidfd_send_signal_simple_success(void)
                return 0;
        }
 
+       signal(SIGUSR1, set_signal_received_on_sigusr1);
+
+       /* Try sending a signal to ourselves via /proc/self. */
        pidfd = open("/proc/self", O_DIRECTORY | O_CLOEXEC);
        if (pidfd < 0)
                ksft_exit_fail_msg(
                        "%s test: Failed to open process file descriptor\n",
                        test_name);
+       err = send_signal(pidfd);
+       if (err)
+               ksft_exit_fail_msg(
+                       "%s test: Error %d on sending pidfd signal\n",
+                       test_name, err);
+       close(pidfd);
 
-       signal(SIGUSR1, set_signal_received_on_sigusr1);
+       /* Now try the same thing only using PIDFD_SELF_THREAD_GROUP. */
+       err = send_signal(PIDFD_SELF_THREAD_GROUP);
+       if (err)
+               ksft_exit_fail_msg(
+                       "%s test: Error %d on PIDFD_SELF_THREAD_GROUP signal\n",
+                       test_name, err);
 
-       ret = sys_pidfd_send_signal(pidfd, SIGUSR1, NULL, 0);
-       close(pidfd);
-       if (ret < 0)
-               ksft_exit_fail_msg("%s test: Failed to send signal\n",
+       /*
+        * Now try the same thing in a thread and assert thread ID is equal to
+        * worker thread ID.
+        */
+       if (pthread_create(&thread, NULL, send_signal_worker,
+                          (void *)(intptr_t)PIDFD_SELF_THREAD))
+               ksft_exit_fail_msg("%s test: Failed to create thread\n",
                                   test_name);
-
-       if (signal_received != 1)
-               ksft_exit_fail_msg("%s test: Failed to receive signal\n",
+       if (pthread_join(thread, &thread_res))
+               ksft_exit_fail_msg("%s test: Failed to join thread\n",
                                   test_name);
+       err = (int)(intptr_t)thread_res;
+       if (err)
+               ksft_exit_fail_msg(
+                       "%s test: Error %d on PIDFD_SELF_THREAD signal\n",
+                       test_name, err);
 
-       signal_received = 0;
        ksft_test_result_pass("%s test: Sent signal\n", test_name);
        return 0;
 }