• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2019 SUSE LLC
4  * Author: Christian Amann <camann@suse.com>
5  */
6 /*
7  * Tests if the pidfd_send_signal syscall behaves
8  * like rt_sigqueueinfo when a pointer to a siginfo_t
9  * struct is passed.
10  */
11 
12 #define _GNU_SOURCE
13 #include <signal.h>
14 #include <stdlib.h>
15 #include "lapi/pidfd_send_signal.h"
16 #include "tst_safe_pthread.h"
17 
18 #define SIGNAL  SIGUSR1
19 #define DATA	777
20 
21 static struct sigaction *sig_action;
22 static int sig_rec;
23 static siginfo_t *uinfo;
24 static int pidfd;
25 
received_signal(int sig,siginfo_t * info,void * ucontext)26 static void received_signal(int sig, siginfo_t *info, void *ucontext)
27 {
28 	if (info && ucontext) {
29 		if (sig == SIGNAL && info->si_value.sival_int == DATA) {
30 			tst_res(TPASS, "Received correct signal and data!");
31 			sig_rec = 1;
32 		} else {
33 			tst_res(TFAIL, "Received wrong signal and/or data!");
34 		}
35 	} else {
36 		tst_res(TFAIL, "Signal handling went wrong!");
37 	}
38 }
39 
handle_thread(void * arg)40 static void *handle_thread(void *arg)
41 {
42 	SAFE_SIGACTION(SIGNAL, sig_action, NULL);
43 	TST_CHECKPOINT_WAKE_AND_WAIT(0);
44 	return arg;
45 }
46 
verify_pidfd_send_signal(void)47 static void verify_pidfd_send_signal(void)
48 {
49 	pthread_t thr;
50 
51 	SAFE_PTHREAD_CREATE(&thr, NULL, handle_thread, NULL);
52 
53 	TST_CHECKPOINT_WAIT(0);
54 
55 	TEST(pidfd_send_signal(pidfd, SIGNAL, uinfo, 0));
56 	if (TST_RET != 0) {
57 		tst_res(TFAIL | TTERRNO, "pidfd_send_signal() failed");
58 		return;
59 	}
60 
61 	TST_CHECKPOINT_WAKE(0);
62 	SAFE_PTHREAD_JOIN(thr, NULL);
63 
64 	if (sig_rec) {
65 		tst_res(TPASS,
66 			"pidfd_send_signal() behaved like rt_sigqueueinfo()");
67 	}
68 }
69 
setup(void)70 static void setup(void)
71 {
72 	pidfd_send_signal_supported();
73 
74 	pidfd = SAFE_OPEN("/proc/self", O_DIRECTORY | O_CLOEXEC);
75 
76 	sig_action = SAFE_MALLOC(sizeof(struct sigaction));
77 
78 	memset(sig_action, 0, sizeof(*sig_action));
79 	sig_action->sa_sigaction = received_signal;
80 	sig_action->sa_flags = SA_SIGINFO;
81 
82 	uinfo = SAFE_MALLOC(sizeof(siginfo_t));
83 
84 	memset(uinfo, 0, sizeof(*uinfo));
85 	uinfo->si_signo = SIGNAL;
86 	uinfo->si_code = SI_QUEUE;
87 	uinfo->si_pid = getpid();
88 	uinfo->si_uid = getuid();
89 	uinfo->si_value.sival_int = DATA;
90 }
91 
cleanup(void)92 static void cleanup(void)
93 {
94 	free(uinfo);
95 	free(sig_action);
96 	if (pidfd > 0)
97 		SAFE_CLOSE(pidfd);
98 }
99 
100 static struct tst_test test = {
101 	.test_all = verify_pidfd_send_signal,
102 	.setup = setup,
103 	.cleanup = cleanup,
104 	.needs_checkpoints = 1,
105 };
106