Message ID | 20240522060321.2223-1-maxj.fnst@fujitsu.com |
---|---|
State | New |
Headers | show |
Series | rt_sigqueueinfo: Add negative tests for rt_sigqueueinfo | expand |
Hi! > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * Copyright (c) 2024 FUJITSU LIMITED. All Rights Reserved. > + * Author: Ma Xinjian <maxj.fnst@fujitsu.com> > + */ > + > +/*\ > + * [Description] > + * > + * Verify that rt_sigqueueinfo(2) fails with > + * > + * - EINVAL when sig is invalid > + * - EPERM when uinfo->si_code is invalid > + * - ESRCH when no thread group matching tgid is found > + */ > +#include <pwd.h> > +#include <signal.h> > +#include "config.h" > +#include "tst_test.h" > + > +#ifdef HAVE_STRUCT_SIGACTION_SA_SIGACTION > +#include "rt_sigqueueinfo.h" > + > +static siginfo_t siginfo_einval; > +static siginfo_t siginfo_eperm; > +static siginfo_t siginfo_esrch; Ideally these should be allocated as guarded buffers: https://linux-test-project.readthedocs.io/en/latest/developers/api_c_tests.html#guarded-buffers You can have a look at signalfd02.c and the .bufs in the tst_test structure initialization. > +static pid_t tgid_notfound = -1; > + > +static struct test_case_t { > + pid_t *tgid; > + int sig; > + siginfo_t *uinfo; > + int expected_errno; > + char *desc; > +} tcases[] = { > + {NULL, -1, &siginfo_einval, EINVAL, "sig is invalid"}, > + {NULL, SIGUSR1, &siginfo_eperm, EPERM, "uinfo->si_code is invalid"}, > + {&tgid_notfound, SIGUSR1, &siginfo_esrch, ESRCH, > + "no thread group matching tgid is found"}, > +}; > + > +static void setup(void) > +{ > + siginfo_einval.si_code = SI_QUEUE; > + siginfo_eperm.si_code = 0; > + siginfo_esrch.si_code = SI_QUEUE; > +} > + > +static void sig_handler(int sig) > +{ > + tst_res(TINFO, "Receive signal %s(%d)", tst_strsig(sig), sig); > +} > + > +static void parent_do(struct test_case_t *tc, pid_t pid) > +{ > + pid_t real_pid; > + > + if (tc->tgid) > + real_pid = *(tc->tgid); > + else > + real_pid = pid; > + > + TST_EXP_FAIL(sys_rt_sigqueueinfo(real_pid, tc->sig, tc->uinfo), > + tc->expected_errno, "%s", tc->desc); > + TST_CHECKPOINT_WAKE(1); > +} > + > +static void child_do(struct test_case_t *tc) > +{ > + struct sigaction sa; > + > + sa.sa_handler = sig_handler; > + SAFE_SIGEMPTYSET(&sa.sa_mask); > + if (tc->sig > 0) > + SAFE_SIGACTION(tc->sig, &sa, NULL); > + else > + SAFE_SIGACTION(SIGUSR1, &sa, NULL); > + > + TST_CHECKPOINT_WAKE(0); > + TST_CHECKPOINT_WAIT(1); The child will never get any signal so all that needs to be done here is to do TST_CHECKPOINT_WAIT() so that the child exists while the parent runs. > +} > + > +static void verify_rt_sigqueueinfo(unsigned int i) > +{ > + struct test_case_t *tc = &tcases[i]; > + pid_t pid = SAFE_FORK(); > + > + if (!pid) { > + child_do(tc); > + exit(0); > + } > + TST_CHECKPOINT_WAIT(0); > + parent_do(tc, pid); > + SAFE_WAITPID(pid, NULL, 0); > +} > + > +static struct tst_test test = { > + .setup = setup, > + .tcnt = ARRAY_SIZE(tcases), > + .test = verify_rt_sigqueueinfo, > + .forks_child = 1, > + .needs_checkpoints = 1, > +}; > + > +#else > + TST_TEST_TCONF("This system does not support rt_sigqueueinfo()"); > +#endif /* HAVE_STRUCT_SIGACTION_SA_SIGACTION */ > -- > 2.39.3 > > > -- > Mailing list info: https://lists.linux.it/listinfo/ltp
diff --git a/runtest/syscalls b/runtest/syscalls index c04359fcd..c6f577de9 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -1200,6 +1200,7 @@ rt_sigaction03 rt_sigaction03 rt_sigprocmask01 rt_sigprocmask01 rt_sigprocmask02 rt_sigprocmask02 rt_sigqueueinfo01 rt_sigqueueinfo01 +rt_sigqueueinfo02 rt_sigqueueinfo02 rt_sigsuspend01 rt_sigsuspend01 rt_sigtimedwait01 rt_sigtimedwait01 rt_tgsigqueueinfo01 rt_tgsigqueueinfo01 diff --git a/testcases/kernel/syscalls/rt_sigqueueinfo/.gitignore b/testcases/kernel/syscalls/rt_sigqueueinfo/.gitignore index 37cd20621..a26811b08 100644 --- a/testcases/kernel/syscalls/rt_sigqueueinfo/.gitignore +++ b/testcases/kernel/syscalls/rt_sigqueueinfo/.gitignore @@ -1 +1,2 @@ /rt_sigqueueinfo01 +/rt_sigqueueinfo02 diff --git a/testcases/kernel/syscalls/rt_sigqueueinfo/rt_sigqueueinfo02.c b/testcases/kernel/syscalls/rt_sigqueueinfo/rt_sigqueueinfo02.c new file mode 100644 index 000000000..dc6b42f46 --- /dev/null +++ b/testcases/kernel/syscalls/rt_sigqueueinfo/rt_sigqueueinfo02.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2024 FUJITSU LIMITED. All Rights Reserved. + * Author: Ma Xinjian <maxj.fnst@fujitsu.com> + */ + +/*\ + * [Description] + * + * Verify that rt_sigqueueinfo(2) fails with + * + * - EINVAL when sig is invalid + * - EPERM when uinfo->si_code is invalid + * - ESRCH when no thread group matching tgid is found + */ +#include <pwd.h> +#include <signal.h> +#include "config.h" +#include "tst_test.h" + +#ifdef HAVE_STRUCT_SIGACTION_SA_SIGACTION +#include "rt_sigqueueinfo.h" + +static siginfo_t siginfo_einval; +static siginfo_t siginfo_eperm; +static siginfo_t siginfo_esrch; + +static pid_t tgid_notfound = -1; + +static struct test_case_t { + pid_t *tgid; + int sig; + siginfo_t *uinfo; + int expected_errno; + char *desc; +} tcases[] = { + {NULL, -1, &siginfo_einval, EINVAL, "sig is invalid"}, + {NULL, SIGUSR1, &siginfo_eperm, EPERM, "uinfo->si_code is invalid"}, + {&tgid_notfound, SIGUSR1, &siginfo_esrch, ESRCH, + "no thread group matching tgid is found"}, +}; + +static void setup(void) +{ + siginfo_einval.si_code = SI_QUEUE; + siginfo_eperm.si_code = 0; + siginfo_esrch.si_code = SI_QUEUE; +} + +static void sig_handler(int sig) +{ + tst_res(TINFO, "Receive signal %s(%d)", tst_strsig(sig), sig); +} + +static void parent_do(struct test_case_t *tc, pid_t pid) +{ + pid_t real_pid; + + if (tc->tgid) + real_pid = *(tc->tgid); + else + real_pid = pid; + + TST_EXP_FAIL(sys_rt_sigqueueinfo(real_pid, tc->sig, tc->uinfo), + tc->expected_errno, "%s", tc->desc); + TST_CHECKPOINT_WAKE(1); +} + +static void child_do(struct test_case_t *tc) +{ + struct sigaction sa; + + sa.sa_handler = sig_handler; + SAFE_SIGEMPTYSET(&sa.sa_mask); + if (tc->sig > 0) + SAFE_SIGACTION(tc->sig, &sa, NULL); + else + SAFE_SIGACTION(SIGUSR1, &sa, NULL); + + TST_CHECKPOINT_WAKE(0); + TST_CHECKPOINT_WAIT(1); +} + +static void verify_rt_sigqueueinfo(unsigned int i) +{ + struct test_case_t *tc = &tcases[i]; + pid_t pid = SAFE_FORK(); + + if (!pid) { + child_do(tc); + exit(0); + } + TST_CHECKPOINT_WAIT(0); + parent_do(tc, pid); + SAFE_WAITPID(pid, NULL, 0); +} + +static struct tst_test test = { + .setup = setup, + .tcnt = ARRAY_SIZE(tcases), + .test = verify_rt_sigqueueinfo, + .forks_child = 1, + .needs_checkpoints = 1, +}; + +#else + TST_TEST_TCONF("This system does not support rt_sigqueueinfo()"); +#endif /* HAVE_STRUCT_SIGACTION_SA_SIGACTION */
Add negative cases for rt_sigqueueinfo(), when errno is EINVAL, EPERM or ESRCH Signed-off-by: Ma Xinjian <maxj.fnst@fujitsu.com> --- runtest/syscalls | 1 + .../syscalls/rt_sigqueueinfo/.gitignore | 1 + .../rt_sigqueueinfo/rt_sigqueueinfo02.c | 108 ++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 testcases/kernel/syscalls/rt_sigqueueinfo/rt_sigqueueinfo02.c