Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/pidfd: add tests for PIDFD_SELF_*

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>

authored by

Lorenzo Stoakes and committed by
Christian Brauner
2bbf47f2 e943271f

+69 -17
+3 -3
tools/testing/selftests/pidfd/pidfd_open_test.c
··· 31 31 #define PIDFD_INFO_CGROUPID (1UL << 0) 32 32 33 33 struct pidfd_info { 34 - __u64 request_mask; 34 + __u64 mask; 35 35 __u64 cgroupid; 36 36 __u32 pid; 37 37 __u32 tgid; ··· 148 148 int main(int argc, char **argv) 149 149 { 150 150 struct pidfd_info info = { 151 - .request_mask = PIDFD_INFO_CGROUPID, 151 + .mask = PIDFD_INFO_CGROUPID, 152 152 }; 153 153 int pidfd = -1, ret = 1; 154 154 pid_t pid; ··· 227 227 getegid(), info.sgid); 228 228 goto on_error; 229 229 } 230 - if ((info.request_mask & PIDFD_INFO_CGROUPID) && info.cgroupid == 0) { 230 + if ((info.mask & PIDFD_INFO_CGROUPID) && info.cgroupid == 0) { 231 231 ksft_print_msg("cgroupid should not be 0 when PIDFD_INFO_CGROUPID is set\n"); 232 232 goto on_error; 233 233 }
+66 -14
tools/testing/selftests/pidfd/pidfd_test.c
··· 42 42 #endif 43 43 } 44 44 45 - static int signal_received; 45 + static pthread_t signal_received; 46 46 47 47 static void set_signal_received_on_sigusr1(int sig) 48 48 { 49 49 if (sig == SIGUSR1) 50 - signal_received = 1; 50 + signal_received = pthread_self(); 51 + } 52 + 53 + static int send_signal(int pidfd) 54 + { 55 + int ret = 0; 56 + 57 + if (sys_pidfd_send_signal(pidfd, SIGUSR1, NULL, 0) < 0) { 58 + ret = -EINVAL; 59 + goto exit; 60 + } 61 + 62 + if (signal_received != pthread_self()) { 63 + ret = -EINVAL; 64 + goto exit; 65 + } 66 + 67 + exit: 68 + signal_received = 0; 69 + return ret; 70 + } 71 + 72 + static void *send_signal_worker(void *arg) 73 + { 74 + int pidfd = (int)(intptr_t)arg; 75 + int ret; 76 + 77 + /* We forward any errors for the caller to handle. */ 78 + ret = send_signal(pidfd); 79 + return (void *)(intptr_t)ret; 51 80 } 52 81 53 82 /* ··· 85 56 */ 86 57 static int test_pidfd_send_signal_simple_success(void) 87 58 { 88 - int pidfd, ret; 59 + int pidfd; 89 60 const char *test_name = "pidfd_send_signal send SIGUSR1"; 61 + pthread_t thread; 62 + void *thread_res; 63 + int err; 90 64 91 65 if (!have_pidfd_send_signal) { 92 66 ksft_test_result_skip( ··· 98 66 return 0; 99 67 } 100 68 69 + signal(SIGUSR1, set_signal_received_on_sigusr1); 70 + 71 + /* Try sending a signal to ourselves via /proc/self. */ 101 72 pidfd = open("/proc/self", O_DIRECTORY | O_CLOEXEC); 102 73 if (pidfd < 0) 103 74 ksft_exit_fail_msg( 104 75 "%s test: Failed to open process file descriptor\n", 105 76 test_name); 106 - 107 - signal(SIGUSR1, set_signal_received_on_sigusr1); 108 - 109 - ret = sys_pidfd_send_signal(pidfd, SIGUSR1, NULL, 0); 77 + err = send_signal(pidfd); 78 + if (err) 79 + ksft_exit_fail_msg( 80 + "%s test: Error %d on sending pidfd signal\n", 81 + test_name, err); 110 82 close(pidfd); 111 - if (ret < 0) 112 - ksft_exit_fail_msg("%s test: Failed to send signal\n", 113 - test_name); 114 83 115 - if (signal_received != 1) 116 - ksft_exit_fail_msg("%s test: Failed to receive signal\n", 117 - test_name); 84 + /* Now try the same thing only using PIDFD_SELF_THREAD_GROUP. */ 85 + err = send_signal(PIDFD_SELF_THREAD_GROUP); 86 + if (err) 87 + ksft_exit_fail_msg( 88 + "%s test: Error %d on PIDFD_SELF_THREAD_GROUP signal\n", 89 + test_name, err); 118 90 119 - signal_received = 0; 91 + /* 92 + * Now try the same thing in a thread and assert thread ID is equal to 93 + * worker thread ID. 94 + */ 95 + if (pthread_create(&thread, NULL, send_signal_worker, 96 + (void *)(intptr_t)PIDFD_SELF_THREAD)) 97 + ksft_exit_fail_msg("%s test: Failed to create thread\n", 98 + test_name); 99 + if (pthread_join(thread, &thread_res)) 100 + ksft_exit_fail_msg("%s test: Failed to join thread\n", 101 + test_name); 102 + err = (int)(intptr_t)thread_res; 103 + if (err) 104 + ksft_exit_fail_msg( 105 + "%s test: Error %d on PIDFD_SELF_THREAD signal\n", 106 + test_name, err); 107 + 120 108 ksft_test_result_pass("%s test: Sent signal\n", test_name); 121 109 return 0; 122 110 }