On i386 there is no need to switch execution mode.
Use 0x23 SS selector for i386, amd64 used 0x4f.
Based on pointers from <maxv>.
Sponsored by <The NetBSD Foundation>
Merge all the PT_WRITE*/PT_READ* and PIOD_* the test cases into the common
body.
Changes:
- treat D and I variations exactly the same
- stop testing 2-3-4 attempts to perform the same read/write operation
- stop testing interlocked (handshake) read/write operations
- rename the tests
- test write to .text section (with D and I type of operations)
New tests:
- bytes_transfer_piod_read_d_8
- bytes_transfer_piod_read_d_16
- bytes_transfer_piod_read_d_32
- bytes_transfer_piod_read_d_64
- bytes_transfer_piod_read_i_8
- bytes_transfer_piod_read_i_16
- bytes_transfer_piod_read_i_32
- bytes_transfer_piod_read_i_64
- bytes_transfer_piod_write_d_8
- bytes_transfer_piod_write_d_16
- bytes_transfer_piod_write_d_32
- bytes_transfer_piod_write_d_64
- bytes_transfer_piod_write_i_8
- bytes_transfer_piod_write_i_16
- bytes_transfer_piod_write_i_32
- bytes_transfer_piod_write_i_64
- bytes_transfer_read_d
- bytes_transfer_read_i
- bytes_transfer_write_d
- bytes_transfer_write_i
- bytes_transfer_piod_read_d_8_text
- bytes_transfer_piod_read_d_16_text
- bytes_transfer_piod_read_d_32_text
- bytes_transfer_piod_read_d_64_text
- bytes_transfer_piod_read_i_8_text
- bytes_transfer_piod_read_i_16_text
- bytes_transfer_piod_read_i_32_text
- bytes_transfer_piod_read_i_64_text
- bytes_transfer_piod_write_d_8_text
- bytes_transfer_piod_write_d_16_text
- bytes_transfer_piod_write_d_32_text
- bytes_transfer_piod_write_d_64_text
- bytes_transfer_piod_write_i_8_text
- bytes_transfer_piod_write_i_16_text
- bytes_transfer_piod_write_i_32_text
- bytes_transfer_piod_write_i_64_text
- bytes_transfer_read_d_text
- bytes_transfer_read_i_text
- bytes_transfer_write_d_text
- bytes_transfer_write_i_text
- bytes_transfer_piod_read_auxv
These tests are now covering all usual code paths.
All tests pass.
The PaX MPROTECT violating ones automatically detect whether to be skipped.
Eliminated 4x more code than removed.
Sponsored by <The NetBSD Foundation>
traceme_vfork_breakpoint used to test SIGTRAP event. Reuse its code for:
SIGSEGV, SIGILL, SIGFPE and SIGBUS.
The SIGILL case is disabled as of now as it required addition of
PTRACE_ILLEGAL_ASM in MD ptrace(2) headers.
Added tests:
- traceme_vfork_crash_trap
- traceme_vfork_crash_segv (renamed from traceme_vfork_breakpoint)
- traceme_vfork_crash_ill (disabled)
- traceme_vfork_crash_fpe
- traceme_vfork_crash_bus
All enabled tests pass.
Sponsored by <The NetBSD Foundation>
Introduce:
- trigger_trap()
- trigger_segv()
- trigger_ill()
- trigger_fpe()
- trigger_bus()
These functions generate appropriate signals caused by crashes.
A debugger is required to collect the crashes regardless of signal masking,
catching or ignoring rules.
While there, append __used argument to can_we_set_dbregs().
Sponsored by <The NetBSD Foundation>
Share code in: attach1, attach2 and race1 in the same function body.
Rename thsee tests to more verbose names:
- tracer_sees_terminaton_before_the_parent
- tracer_sysctl_lookup_without_duplicates
- unrelated_tracer_sees_terminaton_before_the_parent
Rename attach3 to parent_attach_to_its_child.
Rename attach4 to child_attach_to_its_parent.
Share code in attach5, attach6 and attach7 in the same function body and
reanem the tests to:
- tracee_sees_its_original_parent_getppid
- tracee_sees_its_original_parent_sysctl_kinfo_proc2
- tracee_sees_its_original_parent_procfs_status
Reduce the code by around 50%.
No functional change intended. All tests pass.
Sponsored by <The NetBSD Foundation>
These tests emit signal from a tracer/parent to the child and verify the
behavior in the case of SIG_BLOCK (masked) and SIG_IGN (ignored).
The signal is not reported by the child process.
These tests pass.
While there, rename for consistency with other tests:
- traceme_sighandler_catch[1-3] -> traceme_sendsignal_handle[1-3]
- traceme_signal_nohandler[1-5] -> traceme_sendsignal_simple[1-5]
Sponsored by <The NetBSD Foundation>
There are at least four types of SIGTRAP events:
- software/hardware single step (trace trap)
- software breakpoint
- hardware breakpoint/watchpoint
- kernel event (exec, fork, vfork, vfork-done, lwp-create, lwp-exit)
A program can execute software breakpoint without the context of being
traced and this is a regular crash signal emitting SIGTRAP (TRAP_BRKPT).
Rename original trap_* tests (trap_simple, trap_handle, trap_mask,
trap_handle_recurse and trap_ignore) to segv_* tests and restrict them for
SIGSEGV.
Add new tests: trap_* testing the same scenarios as segv_ ones, however
verifying the software breakpoint trap (SIGTRAP).
Keep the original name of h_segv.c, and extend it for software breakpoint
events.
The purpose of these tests is to verify SIGTRAP kernel paths without the
ptrace(2) context.
All tests pass.
Sponsored by <The NetBSD Foundation>
Adapt the test to be independent from the software breakpoint trap
behavior, whether the Program Counter is moved or not. Just kill the
process after catching the expected signal, instead of pretending to resume
it.
This test passes.
Sponsored by <The NetBSD Foundation>
traceme_signal_nohandler2 checks emitting SIGSTOP to a traced process
with the PT_CONTINUE operation.
The expected behavior is to simulate a behavior of receiving SIGSTOP,
generating SIGCHLD to its parent (in this case the debugger) and ability
to call wait(2)-like function receiving the stopped child event.
The previous behavior was unstopping the process and it has been adjusted
in the kernel code.
FreeBSD keeps unstopping a process for emitting SIGSTOP.
Linux handles this scenario in the same way as NetBSD now.
While there, implement the missing bits in the userland ATF test for
traceme_signal_nohandler2: receiving and validating 2nd SIGSTOP event and
continuing the process, followed by its normal termination.
Sponsored by <The NetBSD Foundation>
SIGTSTP, SIGTTIN and SIGTTOU are special case signals ignored in a
vfork(2)ed child. Assert the behavior of raise(2) after calling
PT_TRACE_ME.
Renumber existing traceme_vfork_raise tests.
Sponsored by <The NetBSD Foundation>
raise(SIGSTOP) is now handled correctly by the kernel, in a child that
vfork(2)ed and called PT_TRACE_ME.
Implement a helper process emitting SIGKILL to a stopped child of a
vfork(2)ed process.
Sponsored by <The NetBSD Foundation>
Keep the traditional BSD behavior masking SIGTSTP, SIGTTIN and SIGTTOU in
a vfork(2)ed child before exec(3)/exit(3). This is useful in shells and
prevents deadlocking, when a parent cannot unstop the sleeping child.
Change the behavior for SIGSTOP. This signal is by design not maskable and
this property shall be obeyed without exceptions. The STOP behavior is
expected in the context of debuggers and useful in standalone programs.
It is still possible to stop a vfork(2)ed child, however it requires
proc.curproc.stopfork=1, but it is not a flexible solution.
FreeBSD and OpenBSD keep masking SIGSTOP in a vfork(2)ed child.
Linux does not mask stop signals in the same scenarios.
This fixes ATF test: t_vfork:raise2.
No known regressions reported in the existing ATF tests.
Discussed with <kre>
Sponsored by <The NetBSD Foundation>
In traceme* tests after validate_status_stopped() include additional check
the verify the received signal with PT_GET_SIGINFO.
All tests passes.
Sponsored by <The NetBSD Foundation>
Set new description to:
- "Verify PT_TRACE_ME followed by raise of " #sig " in a vfork(2)ed "
"child"
The previous one was copy pasted from a different ATF test and not changed.
Sponsored by <The NetBSD Foundation>
Verify software breakpoint in a vfork(2)ed child.
The expected behavior is not to route this signal to the parent, even if
that parent is a tracer. The parent cannot handle it and it would lead to
the deadlock.
This test passes correctly.
Sponsored by <The NetBSD Foundation>
Follow the FreeBSD approach of not routing signals to the parent that is
a became tracer after calling PT_TRACE_ME by the vfork(2)ed child (before
exec(3)/exit(3)).
Now if a child calls raise(3), the signal is processed directly to this
child.
Add new ATF ptrace(2) tests:
- traceme_vfork_raise1 (SIGKILL)
- traceme_vfork_raise2 (SIGSTOP) // temporarily disabled
- traceme_vfork_raise3 (SIGABRT)
- traceme_vfork_raise4 (SIGHUP)
- traceme_vfork_raise5 (SIGCONT)
The FreeBSD implementation introduces P_PPTRACE for this special case.
Right know keep opencoding check of this case in the kernel. It might be
refactored in future.
The Linux kernel does not follow this approach and causes dead locking of
the processes (parent and child).
Defer handling SIGSTOP into future.
This is an intermediate step towards correct handling of fork(2) and
vfork(2) in the context of ptrace(2).
All new tests pass.
There are no regressions in existing ATF ptrace(2) tests.
Sponsored by <The NetBSD Foundation>
By a mistake this file started to include <sys/mman.h>
This is not needed.
The include was intended to be add just in t_ptrace_wait.c.
Sponsored by <The NetBSD Foundation>
Do not call _exit() from the child, ad this code shall not be reached.
Put there assert().
No functional change. The test still passes.
Sponsored by <The NetBSD Foundation>
The original expolit and mitigation have been developed by Maxime Villard.
I've reworked the shared code and adapted for the ATF context.
I've included PIE-aware version (RIP/EIP relative) and introduced
additional comments to the explanation how to trigger the flaw.
This test passes on NetBSD/8.99.17.
Sponsored by <The NetBSD Foundation>
Move the can_we_set_dbregs() auxiliary function from t_ptrace_x86_wait.h
to a common file t_ptrace_wait.h. This allows using this function for
checking whether the DBREGS set operations in ptrace(2) are accessible for
a user.
Sponsored by <The NetBSD Foundation>
Add new cc and c++ tests to check whether UBSan works.
These tests are prepared for GCC (in base) and Clang (with external patches).
Enable these tests for all ports by default, just verify whether we are
using GCC/Clang or a compatible compiler.
Add five equivalent C and C++ tests:
- Integer addition overflow
- Integer divide by zero
- Integer negation overflow
- Integer subtraction overflow
- VLA out of bounds
All tests pass on NetBSD/amd64.
Patch submitted by <Harry Pantazis>
Minor cleanup by <myself>
Add support for tracing vfork(2) events in the context of ptrace(2).
This API covers other frontends to fork1(9) like posix_spawn(2) or clone(2),
if they cause parent to wait for exec(2) or exit(2) of the child.
Changes:
- Add new argument to sigswitch() determining whether we need to acquire
the proc_lock or whether it's already held.
- Refactor fork1(9) for fork(2) and vfork(2)-like events.
Call sigswitch() from fork(1) for forking or vforking parent, instead of
emitting kpsignal(9). We need to emit the signal and suspend the parent,
returning to user and relock proc_lock.
- Add missing prototype for proc_stop_done() in kern_sig.c.
- Make sigswitch a public function accessible from other kernel code
including <sys/signalvar.h>.
- Remove an entry about unimplemented PTRACE_VFORK in the ptrace(2) man page.
- Permin PTRACE_VFORK in the ptrace(2) frontend for userland.
- Remove expected failure for unimplemented PTRACE_VFORK tests in the ATF
ptrace(2) test-suite.
- Relax signal routing constraints under a debugger for a vfork(2)ed child.
This intended to protect from signaling a parent of a vfork(2)ed child that
called PT_TRACE_ME, but wrongly misrouted other signals in vfork(2)
use-cases.
Add XXX comments about still existing problems and future enhancements:
- correct vfork(2) + PT_TRACE_ME handling.
- fork1(2) handling of scenarios when a process is collected in valid but
rare cases.
All ATF ptrace(2) fork[1-8] and vfork[1-8] tests pass.
Fix PR kern/51630 by Kamil Rytarowski (myself).
Sponsored by <The NetBSD Foundation>
Added:
- traceme_pid1_parent
Assert that a process cannot mark its parent a debugger twice
- traceme_twice
Verify that PT_TRACE_ME is not allowed when our parent is PID1
All tests pass.
Sponsored by <The NetBSD Foundation>
This test checks raise(SIGKILL). If we enter the kernel with this signal
we report a signaled child in a debugger, not stopped with an option to
make an action.
FreeBSD behaves differently and allows intercepting this event in a tracer.
Follow the Linux behavior.
If we really want to prevent raise(SIGKILL) from signaling the tracee, we
still can breakpoint raise(3) and alter the syscall arguments (or use
the PT_SYSCALL mode). If we are already in the kernel, SIGKILL always means
killing the process, whether or not traced and the source of SIGKILL.
This tests passes on NetBSD without kernel changes.
Sponsored by <The NetBSD Foundation>
Replace traceme3 with new ATF tests using diverse signals:
- traceme_signal_nohandler1 SIGKILL
- traceme_signal_nohandler2 SIGSTOP (temporarily disabled)
- traceme_signal_nohandler3 SIGABRT (emits core dump)
- traceme_signal_nohandler4 SIGHUP
- traceme_signal_nohandler5 SIGCONT
These SIGSTOP test does not work properly right now as it unstops the
traccee.
Sponsored by <The NetBSD Foundation>
Replace traceme2 with 3 tests:
- traceme_sighandler_catch1
- traceme_sighandler_catch2
- traceme_sighandler_catch3
These tests are verified with PT_TRACE_ME for: SIGHUP, SIGCONT and SIGABRT.
We don't want tests all signals (this is a domain for a fuzzer), but we want
to cover tests with signals from different groups.
All tests pass.
Sponsored by <The NetBSD Foundation>
Use common bode for these tests and a macro 1-liner to define a new test.
Test the same scenarios for 5 signals:
- SIGKILL (temporarily disabled)
- SIGSTOP
- SIGABRT
- SIGHUP
- SIGCONT
These tests call: raise(sig). It's actually important to assert their
behavior for tests that are from different kinds.
The SIGKILL test is work in progress. It can be caught by a debugger on the
FreeBSD kernel, but it's causing a signaled event in a debugger on Linux.
NetBSD is right now in one of the camps, but research whether this is a bug
or feature is in progress.
Sponsored by <The NetBSD Foundation>
Currently this test case will fail, a fix is coming soon (not worth
marking this as an expected failure.)
This test case and the initial bug report comes from
Martijn Dekker's modernish (shell/test set).
Add CPP syntax sugare to define each fork-like test within a single line
of code with less than 80 columns.
This is a preparation for new fork-like scenarios where we detach either
child and/or parent with PT_DETACH.
The code could be still reduced to smaller number of columns, instead of:
FORK_TEST(fork1, DSCR(fork,0,0,0,0,0), fork, F, F, F, F, F)
we could perhaps need 50% of it, as the data is duplicated.
On the other hand the line is already short and taking only a single line.
No functional change intended.
Sponsored by <The NetBSD Foundation>
Add new tests:
- tests/usr.bin/cc/t_asan_poison.sh
- tests/usr.bin/c++/t_asan_poison.sh
These tests verify the following build options:
- regular
- profile
- pic
- pie
- compat32
- (static unsupported)
These tests verify whether ASan code can include compiler and sanitizer
specific header: <sanitizer/asan_interface.h>. The testing code checks
the ASAN_POISON_MEMORY_REGION() functionality, poisoning valid memory and
asserting that it triggers expected failure.
Patch submitted by <Siddharth Muralee>
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>
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>
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>
Add new C and C++ tests:
- t_asan_double_free
- t_asan_global_buffer_overflow
- t_asan_heap_overflow
- t_asan_off_by_one
- t_asan_uaf
Each tests checks:
- regular build
- 32-bit
- PIC
- PIE
- profile
These tests require paxctl(8) to disable ASLR in order to work in a
predictable way. This is especially true for all !regular builds with
additional compiler flags.
There are no static variations of these tests as this mode is not supported
in upstream ASan.
Enable these tests on amd64 and i386.
This is part two patch, adding the remaining C++ changes.
Patch submitted by <Siddharth Muralee>
Additional polishing by myself.
Add new C and C++ tests:
- t_asan_double_free
- t_asan_global_buffer_overflow
- t_asan_heap_overflow
- t_asan_off_by_one
- t_asan_uaf
Each tests checks:
- regular build
- 32-bit
- PIC
- PIE
- profile
These tests require paxctl(8) to disable ASLR in order to work in a
predictable way. This is especially true for all !regular builds with
additional compiler flags.
There are no static variations of these tests as this mode is not supported
in upstream ASan.
Enable these tests on amd64 and i386.
Patch submitted by <Siddharth Muralee>
Additional polishing by myself.
If we do so, there will remain one route that is of a preceding address, but
that behavior is not documented and may be changed in the future. Tests
shouldn't rely on such a unstable behavior.
New tests attempting to kill, stop, drop or revive a zombie:
- signal1 (SIGKILL)
- signal2 (SIGSTOP)
- signal3 (SIGABRT)
- signal4 (SIGHUP)
- signal5 (SIGCONT)
New test race1 verifying whether there are any kernel races when processing
signals to zombies, executing in a loop for 5 seconds.
These tests were inspired by a kernel unexpected behavior when a lookup
of a dying process could result in two detected entities once as an alive
process and once as a zombie.
race1 is similar to t_ptrace_wait* race1, however without ptrace(2) involved.
Sponsored by <The NetBSD Foundation>
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.
The bug in the kernel is now gone and this test is expected to pass
correctly.
Sponsored by <The NetBSD Foundation>
Add await_zombie_raw() that is the same as await_zombie(), whith an
addition of additional "useconds_t ms" parameter indicating delays between
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 entries
for KERN_PROC_PID.
Sponsored by <The NetBSD Foundation>
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>
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 being
investigated.
Sponsored by <The NetBSD Foundation>
This code after refactoring stopped calling functions that were designed
to trigger expected behavior and thus, tests were breaking.
Sponsored by <The NetBSD Foundation>
These operations cloned Linux's specific PTRACE_GETSIGMASK / PTRACE_SETSIGMASK.
This feature was useful in applications like rr/criu/reptyr-like, where
the ptrace(2) interface is abused for the purpose of constructing an arbitrary
process. It's not reliable and not portable. For the NetBSD case it will be
better to invent something dedicated for serializing and deserializing a
process with threads.
Noted on tech-toolchain@ and blog entry
"LLDB restoration and return to ptrace(2)"
https://blog.netbsd.org/tnf/entry/lldb_restoration_and_return_to
The <inttypes.h> user-land header is required for PRI types.
We were including indirectly <sys/inttypes.h> through <sys/*.h> sources,
and this worked for most of the ports.
This fixes indirectly a build for MIPS (tested ports: arc and hpcmips),
where PRI types (PRIxREGISTER) were undefined.
Noted by <uwe>.