Pull up following revision(s) (requested by kamil in ticket #711):
tests/lib/libc/sys/t_ptrace_wait.c: revision 1.24-1.31 tests/lib/libc/sys/t_ptrace_wait.h: revision 1.2 tests/lib/libc/sys/t_ptrace_x86_wait.h: revision 1.4,1.5 tests/lib/libc/sys/msg.h: revision 1.2 Correct all ATF failures in t_ptrace_x86_wait.h (debug registers) This code after refactoring stopped calling functions that were designed to trigger expected behavior and thus, tests were breaking. Sponsored by <The NetBSD Foundation> ATF: Correct a race bug in attach2 (t_ptrace_wait*) At the end of the test we resume a tracer and expect to observe it to collect the debuggee. We cannot from a parent point of view wait for collecting it with WNOHANG without a race. Remove the WNOHANG option from wait*(2) call. This corrects one type of race. This test is still racy for some other and unknown reason and this is bei= ng investigated. Sponsored by <The NetBSD Foundation> ATF: Reenable attach2 in t_ptrace_wait* The primary race specific to this test has been fixed in previous commit (wrong WNOHANG). This test is still racy and breaks like once every 30,000 execution. This is down like from once from every 100th execution in the past. The remaning race is not specific to attach2 and I can reproduce it with at least attach1. It still looks like being specific to NetBSD and it's not reproducible on Linux and FreeBSD. Perhaps a bug with pipe(2)/write(2= )/ read(2) or close to these features. Sponsored by <The NetBSD Foundation> Add a new function in ATF t_ptrace_wait*: await_zombie_raw() Add await_zombie_raw() that is the same as await_zombie(), whith an addition of additional "useconds_t ms" parameter indicating delays betwee= n new polling for a zombie process. This new function will be used for testing a race condition that has been= observed occassionally crashing a test case -- returning duplicate entrie= s for KERN_PROC_PID. Sponsored by <The NetBSD Foundation> ATF t_ptrace_wait*: Disable debug messages in msg.h msg.h is a dummy IPC interface. Disable additional debugging logging here, especially wanted in race* tests. Sponsored by <The NetBSD Foundation> ATF: Add new test race1 in t_ptrace_wait* Reuse the attach1's test body for race1. Add a new test race1: Assert that await_zombie() in attach1 always finds a single process and no other error is reported race1 requires HAVE_PID in wait(2)-like function. This test is executed in a loop for 5 seconds (16k iterations on Intel i7= ). A buggy kernel was asserting an error within this timeframe almost always= =2E The bug in the kernel is now gone and this test is expected to pass correctly. Sponsored by <The NetBSD Foundation> Add check in ATF tests for security.models.extensions.user_set_dbregs Introduce a new function can_we_set_dbregs() in the ATF ptrace(2) tests. It uses lazy-bool evaluation whether a process can call PT_SETDBREGS. In case of not being able to do so, print a message and mark a test as skipped: Either run this test as root or set sysctl(3) security.models.extensions.user_set_dbregs to 1 No functional change intended to the code flow of the existing tested scenarios. Sponsored by <The NetBSD Foundation> Improve documentation of the ATF test t_ptrace_wait*: traceme2 Set the description to: Verify that a signal emitted by a tracer to a child is caught by a signal handler. Sponsored by <The NetBSD Foundation> Merge code in tests: fork1 and vfork1 (ATF t_ptrace_wait*) Marge bodies of two tests into the same function. Add few checks for regular fork or not (vfork). Sponsored by <The NetBSD Foundation> ATF: ptrace: Merge code in fork2 and vfork2 tests with (v)fork1 ones Reduce code duplication, use the same function body with conditional switches. Sponsored by <The NetBSD Foundation> ATF t_ptrace_wait* refactoring: vforkdone1 and vforkdone2 Merge vforkdone1 and vforkdone2 into other fork tests and reuse the same function body fork_test(). There is an implicit enhancement in vforkdone2 that it was skipping PTRACE_VFORK check. This test is now marked as expected failure. PR kern/51630 Sponsored by <The NetBSD Foundation> Cover more fork/vfork/vforkdone scenarios in ATF ptrace(2) tests Use a shared common body for all the tests: fork1..fork8, vfork1..vfork8.= Merge vforkdone1 and vforkdone2 into vfork* tests. All the (v?)fork[1-8] tests cover: - calling either fork(2) or vfork(2) - tracking either enabled or disabled FORK, VFORK or VFORK_DONE All the PTRACE_VFORK tests are marked as expected failure. Sponsored by <The NetBSD Foundation>
This commit is contained in:
parent
f5c0c2c48c
commit
bb1b4489c6
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: msg.h,v 1.1 2017/04/02 21:44:00 kamil Exp $ */
|
||||
/* $NetBSD: msg.h,v 1.1.8.1 2018/04/12 13:02:21 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2016 The NetBSD Foundation, Inc.
|
||||
|
@ -70,7 +70,7 @@ msg_write_child(const char *info, struct msg_fds *fds, void *msg, size_t len)
|
|||
CLOSEFD(fds->cfd[1]);
|
||||
CLOSEFD(fds->pfd[0]);
|
||||
|
||||
printf("Send %s\n", info);
|
||||
// printf("Send %s\n", info);
|
||||
rv = write(fds->pfd[1], msg, len);
|
||||
if (rv != (ssize_t)len)
|
||||
return 1;
|
||||
|
@ -88,7 +88,7 @@ msg_write_parent(const char *info, struct msg_fds *fds, void *msg, size_t len)
|
|||
CLOSEFD(fds->pfd[1]);
|
||||
CLOSEFD(fds->cfd[0]);
|
||||
|
||||
printf("Send %s\n", info);
|
||||
// printf("Send %s\n", info);
|
||||
rv = write(fds->cfd[1], msg, len);
|
||||
if (rv != (ssize_t)len)
|
||||
return 1;
|
||||
|
@ -106,7 +106,7 @@ msg_read_parent(const char *info, struct msg_fds *fds, void *msg, size_t len)
|
|||
CLOSEFD(fds->pfd[1]);
|
||||
CLOSEFD(fds->cfd[0]);
|
||||
|
||||
printf("Wait %s\n", info);
|
||||
// printf("Wait %s\n", info);
|
||||
rv = read(fds->pfd[0], msg, len);
|
||||
if (rv != (ssize_t)len)
|
||||
return 1;
|
||||
|
@ -124,7 +124,7 @@ msg_read_child(const char *info, struct msg_fds *fds, void *msg, size_t len)
|
|||
CLOSEFD(fds->cfd[1]);
|
||||
CLOSEFD(fds->pfd[0]);
|
||||
|
||||
printf("Wait %s\n", info);
|
||||
// printf("Wait %s\n", info);
|
||||
rv = read(fds->cfd[0], msg, len);
|
||||
if (rv != (ssize_t)len)
|
||||
return 1;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: t_ptrace_wait.h,v 1.1 2017/04/02 21:44:00 kamil Exp $ */
|
||||
/* $NetBSD: t_ptrace_wait.h,v 1.1.8.1 2018/04/12 13:02:21 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2016 The NetBSD Foundation, Inc.
|
||||
|
@ -328,7 +328,7 @@ forkee_status_stopped(int status, int expected)
|
|||
|
||||
/* This function is currently designed to be run in the main/parent process */
|
||||
static void __used
|
||||
await_zombie(pid_t process)
|
||||
await_zombie_raw(pid_t process, useconds_t ms)
|
||||
{
|
||||
struct kinfo_proc2 p;
|
||||
size_t len = sizeof(p);
|
||||
|
@ -351,10 +351,19 @@ await_zombie(pid_t process)
|
|||
if (p.p_stat == LSZOMB)
|
||||
break;
|
||||
|
||||
ATF_REQUIRE(usleep(1000) == 0);
|
||||
if (ms > 0) {
|
||||
ATF_REQUIRE(usleep(ms) == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void __used
|
||||
await_zombie(pid_t process)
|
||||
{
|
||||
|
||||
await_zombie_raw(process, 1000);
|
||||
}
|
||||
|
||||
/* Happy number sequence -- this function is used to just consume cpu cycles */
|
||||
#define HAPPY_NUMBER 1
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: t_ptrace_x86_wait.h,v 1.1.8.1 2018/02/25 20:59:46 snj Exp $ */
|
||||
/* $NetBSD: t_ptrace_x86_wait.h,v 1.1.8.2 2018/04/12 13:02:21 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2016 The NetBSD Foundation, Inc.
|
||||
|
@ -57,6 +57,33 @@ union u {
|
|||
} bits;
|
||||
};
|
||||
|
||||
static bool
|
||||
can_we_set_dbregs(void)
|
||||
{
|
||||
static long euid = -1;
|
||||
static int user_set_dbregs = -1;
|
||||
size_t user_set_dbregs_len = sizeof(user_set_dbregs);
|
||||
|
||||
if (euid == -1)
|
||||
euid = geteuid();
|
||||
|
||||
if (euid == 0)
|
||||
return true;
|
||||
|
||||
if (user_set_dbregs == -1) {
|
||||
if (sysctlbyname("security.models.extensions.user_set_dbregs",
|
||||
&user_set_dbregs, &user_set_dbregs_len, NULL, 0)
|
||||
== -1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (user_set_dbregs > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
ATF_TC(dbregs_print);
|
||||
ATF_TC_HEAD(dbregs_print, tc)
|
||||
{
|
||||
|
@ -135,6 +162,11 @@ dbreg_preserve(int reg, enum dbreg_preserve_mode mode)
|
|||
size_t i;
|
||||
int watchme;
|
||||
|
||||
if (!can_we_set_dbregs()) {
|
||||
atf_tc_skip("Either run this test as root or set sysctl(3) "
|
||||
"security.models.extensions.user_set_dbregs to 1");
|
||||
}
|
||||
|
||||
DPRINTF("Before forking process PID=%d\n", getpid());
|
||||
SYSCALL_REQUIRE((child = fork()) != -1);
|
||||
if (child == 0) {
|
||||
|
@ -389,6 +421,11 @@ dbregs_trap_variable(int reg, int cond, int len, bool write)
|
|||
struct ptrace_siginfo info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
if (!can_we_set_dbregs()) {
|
||||
atf_tc_skip("Either run this test as root or set sysctl(3) "
|
||||
"security.models.extensions.user_set_dbregs to 1");
|
||||
}
|
||||
|
||||
dr7.raw = 0;
|
||||
switch (reg) {
|
||||
case 0:
|
||||
|
@ -422,7 +459,7 @@ dbregs_trap_variable(int reg, int cond, int len, bool write)
|
|||
if (write)
|
||||
watchme = 1;
|
||||
else
|
||||
DPRINTF("watchme=%d\n", watchme);
|
||||
printf("watchme=%d\n", watchme);
|
||||
|
||||
DPRINTF("Before raising %s from child\n", strsignal(sigval));
|
||||
FORKEE_ASSERT(raise(sigval) == 0);
|
||||
|
@ -897,7 +934,6 @@ ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_read_byte, tc)
|
|||
/* 0b11 -- break on data write&read */
|
||||
/* 0b00 -- 1 byte */
|
||||
|
||||
atf_tc_expect_fail("wrong signal");
|
||||
dbregs_trap_variable(0, 3, 0, false);
|
||||
}
|
||||
|
||||
|
@ -914,7 +950,6 @@ ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_read_byte, tc)
|
|||
/* 0b11 -- break on data write&read */
|
||||
/* 0b00 -- 1 byte */
|
||||
|
||||
atf_tc_expect_fail("wrong signal");
|
||||
dbregs_trap_variable(1, 3, 0, false);
|
||||
}
|
||||
|
||||
|
@ -931,7 +966,6 @@ ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_read_byte, tc)
|
|||
/* 0b11 -- break on data write&read */
|
||||
/* 0b00 -- 1 byte */
|
||||
|
||||
atf_tc_expect_fail("wrong signal");
|
||||
dbregs_trap_variable(2, 3, 0, false);
|
||||
}
|
||||
|
||||
|
@ -948,7 +982,6 @@ ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_read_byte, tc)
|
|||
/* 0b11 -- break on data write&read */
|
||||
/* 0b00 -- 1 byte */
|
||||
|
||||
atf_tc_expect_fail("wrong signal");
|
||||
dbregs_trap_variable(3, 3, 0, false);
|
||||
}
|
||||
|
||||
|
@ -965,7 +998,6 @@ ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_read_2bytes, tc)
|
|||
/* 0b11 -- break on data write&read */
|
||||
/* 0b01 -- 2 bytes */
|
||||
|
||||
atf_tc_expect_fail("wrong signal");
|
||||
dbregs_trap_variable(0, 3, 1, false);
|
||||
}
|
||||
|
||||
|
@ -982,7 +1014,6 @@ ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_read_2bytes, tc)
|
|||
/* 0b11 -- break on data write&read */
|
||||
/* 0b01 -- 2 bytes */
|
||||
|
||||
atf_tc_expect_fail("wrong signal");
|
||||
dbregs_trap_variable(1, 3, 1, false);
|
||||
}
|
||||
|
||||
|
@ -999,7 +1030,6 @@ ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_read_2bytes, tc)
|
|||
/* 0b11 -- break on data write&read */
|
||||
/* 0b01 -- 2 bytes */
|
||||
|
||||
atf_tc_expect_fail("wrong signal");
|
||||
dbregs_trap_variable(2, 3, 1, false);
|
||||
}
|
||||
|
||||
|
@ -1016,7 +1046,6 @@ ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_read_2bytes, tc)
|
|||
/* 0b11 -- break on data write&read */
|
||||
/* 0b01 -- 2 bytes */
|
||||
|
||||
atf_tc_expect_fail("wrong signal");
|
||||
dbregs_trap_variable(3, 3, 1, false);
|
||||
}
|
||||
|
||||
|
@ -1033,7 +1062,6 @@ ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_read_4bytes, tc)
|
|||
/* 0b11 -- break on data write&read */
|
||||
/* 0b11 -- 4 bytes */
|
||||
|
||||
atf_tc_expect_fail("wrong signal");
|
||||
dbregs_trap_variable(0, 3, 3, false);
|
||||
}
|
||||
|
||||
|
@ -1050,7 +1078,6 @@ ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_read_4bytes, tc)
|
|||
/* 0b11 -- break on data write&read */
|
||||
/* 0b11 -- 4 bytes */
|
||||
|
||||
atf_tc_expect_fail("wrong signal");
|
||||
dbregs_trap_variable(1, 3, 3, false);
|
||||
}
|
||||
|
||||
|
@ -1067,7 +1094,6 @@ ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_read_4bytes, tc)
|
|||
/* 0b11 -- break on data write&read */
|
||||
/* 0b11 -- 4 bytes */
|
||||
|
||||
atf_tc_expect_fail("wrong signal");
|
||||
dbregs_trap_variable(2, 3, 3, false);
|
||||
}
|
||||
|
||||
|
@ -1084,7 +1110,6 @@ ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_read_4bytes, tc)
|
|||
/* 0b11 -- break on data write&read */
|
||||
/* 0b11 -- 4 bytes */
|
||||
|
||||
atf_tc_expect_fail("wrong signal");
|
||||
dbregs_trap_variable(3, 3, 3, false);
|
||||
}
|
||||
|
||||
|
@ -1110,11 +1135,14 @@ ATF_TC_BODY(dbregs_dr0_trap_code, tc)
|
|||
volatile int watchme = 1;
|
||||
union u dr7;
|
||||
|
||||
atf_tc_expect_fail("wrong signal");
|
||||
|
||||
struct ptrace_siginfo info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
if (!can_we_set_dbregs()) {
|
||||
atf_tc_skip("Either run this test as root or set sysctl(3) "
|
||||
"security.models.extensions.user_set_dbregs to 1");
|
||||
}
|
||||
|
||||
dr7.raw = 0;
|
||||
dr7.bits.global_dr0_breakpoint = 1;
|
||||
dr7.bits.condition_dr0 = 0; /* 0b00 -- break on code execution */
|
||||
|
@ -1129,7 +1157,7 @@ ATF_TC_BODY(dbregs_dr0_trap_code, tc)
|
|||
DPRINTF("Before raising %s from child\n", strsignal(sigval));
|
||||
FORKEE_ASSERT(raise(sigval) == 0);
|
||||
|
||||
DPRINTF("check_happy(%d)=%d\n", watchme, check_happy(watchme));
|
||||
printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
|
||||
|
||||
DPRINTF("Before raising %s from child\n", strsignal(sigval));
|
||||
FORKEE_ASSERT(raise(sigval) == 0);
|
||||
|
@ -1242,7 +1270,10 @@ ATF_TC_BODY(dbregs_dr1_trap_code, tc)
|
|||
struct ptrace_siginfo info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
atf_tc_expect_fail("wrong signal");
|
||||
if (!can_we_set_dbregs()) {
|
||||
atf_tc_skip("Either run this test as root or set sysctl(3) "
|
||||
"security.models.extensions.user_set_dbregs to 1");
|
||||
}
|
||||
|
||||
dr7.raw = 0;
|
||||
dr7.bits.global_dr1_breakpoint = 1;
|
||||
|
@ -1258,7 +1289,7 @@ ATF_TC_BODY(dbregs_dr1_trap_code, tc)
|
|||
DPRINTF("Before raising %s from child\n", strsignal(sigval));
|
||||
FORKEE_ASSERT(raise(sigval) == 0);
|
||||
|
||||
DPRINTF("check_happy(%d)=%d\n", watchme, check_happy(watchme));
|
||||
printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
|
||||
|
||||
DPRINTF("Before raising %s from child\n", strsignal(sigval));
|
||||
FORKEE_ASSERT(raise(sigval) == 0);
|
||||
|
@ -1371,7 +1402,11 @@ ATF_TC_BODY(dbregs_dr2_trap_code, tc)
|
|||
struct ptrace_siginfo info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
atf_tc_expect_fail("wrong signal");
|
||||
if (!can_we_set_dbregs()) {
|
||||
atf_tc_skip("Either run this test as root or set sysctl(3) "
|
||||
"security.models.extensions.user_set_dbregs to 1");
|
||||
}
|
||||
|
||||
dr7.raw = 0;
|
||||
dr7.bits.global_dr2_breakpoint = 1;
|
||||
dr7.bits.condition_dr2 = 0; /* 0b00 -- break on code execution */
|
||||
|
@ -1386,7 +1421,7 @@ ATF_TC_BODY(dbregs_dr2_trap_code, tc)
|
|||
DPRINTF("Before raising %s from child\n", strsignal(sigval));
|
||||
FORKEE_ASSERT(raise(sigval) == 0);
|
||||
|
||||
DPRINTF("check_happy(%d)=%d\n", watchme, check_happy(watchme));
|
||||
printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
|
||||
|
||||
DPRINTF("Before raising %s from child\n", strsignal(sigval));
|
||||
FORKEE_ASSERT(raise(sigval) == 0);
|
||||
|
@ -1499,7 +1534,11 @@ ATF_TC_BODY(dbregs_dr3_trap_code, tc)
|
|||
struct ptrace_siginfo info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
atf_tc_expect_fail("wrong signal");
|
||||
if (!can_we_set_dbregs()) {
|
||||
atf_tc_skip("Either run this test as root or set sysctl(3) "
|
||||
"security.models.extensions.user_set_dbregs to 1");
|
||||
}
|
||||
|
||||
dr7.raw = 0;
|
||||
dr7.bits.global_dr3_breakpoint = 1;
|
||||
dr7.bits.condition_dr3 = 0; /* 0b00 -- break on code execution */
|
||||
|
@ -1514,7 +1553,7 @@ ATF_TC_BODY(dbregs_dr3_trap_code, tc)
|
|||
DPRINTF("Before raising %s from child\n", strsignal(sigval));
|
||||
FORKEE_ASSERT(raise(sigval) == 0);
|
||||
|
||||
DPRINTF("check_happy(%d)=%d\n", watchme, check_happy(watchme));
|
||||
printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
|
||||
|
||||
DPRINTF("Before raising %s from child\n", strsignal(sigval));
|
||||
FORKEE_ASSERT(raise(sigval) == 0);
|
||||
|
@ -1632,6 +1671,11 @@ dbregs_dont_inherit_lwp(int reg)
|
|||
struct dbreg r1;
|
||||
struct dbreg r2;
|
||||
|
||||
if (!can_we_set_dbregs()) {
|
||||
atf_tc_skip("Either run this test as root or set sysctl(3) "
|
||||
"security.models.extensions.user_set_dbregs to 1");
|
||||
}
|
||||
|
||||
DPRINTF("Before forking process PID=%d\n", getpid());
|
||||
SYSCALL_REQUIRE((child = fork()) != -1);
|
||||
if (child == 0) {
|
||||
|
@ -1803,6 +1847,11 @@ dbregs_dont_inherit_execve(int reg)
|
|||
struct ptrace_siginfo info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
if (!can_we_set_dbregs()) {
|
||||
atf_tc_skip("Either run this test as root or set sysctl(3) "
|
||||
"security.models.extensions.user_set_dbregs to 1");
|
||||
}
|
||||
|
||||
DPRINTF("Before forking process PID=%d\n", getpid());
|
||||
SYSCALL_REQUIRE((child = fork()) != -1);
|
||||
if (child == 0) {
|
||||
|
|
Loading…
Reference in New Issue