Repository navigation
Assertion `!!(blocked & mask) == is_sig_blocked(sig)' failed to hold. SIGTRAP is not blocked #1879
Copy link
Copy link
Closed
Description
Using rr with mochitests seems to be broken now. I'm on Ubuntu 16.04 with latest updates. I have pulled the latest rr (0f36df5) and rebuilt. I have the latest version of ff code from central (060f80b690b8). This seems to be completely repeatable. As an example, if I run this command:
./mach mochitest dom/media/tests/mochitest/test_peerConnection_basicAudio.html --keep-open=false --debugger=rr
I see:
[FATAL /home/mfroman/rr/rr/src/RecordTask.cc:1110:verify_signal_states() errno: SUCCESS]
(task 16128 (rec:16128) at time 285111)
-> Assertion `!!(blocked & mask) == is_sig_blocked(sig)' failed to hold. SIGTRAP is not blocked
[FATAL /home/mfroman/rr/rr/src/log.cc:284:emergency_debug() errno: SUCCESS] (session doesn't look interactive, aborting emergency debugging)
TEST-INFO | Main app process: killed by SIGIOT
Buffered messages finished
1 ERROR TEST-UNEXPECTED-FAIL | automation.py | application terminated with exit code -6
runtests.py | Application ran for: 0:01:40.504514
zombiecheck | Reading PID log: /tmp/tmpfWkP9Wpidlog
==> process 15958 launched child process 15977
==> process 15958 launched child process 16047
zombiecheck | Checking for orphan process with PID: 15977
zombiecheck | Checking for orphan process with PID: 16047
After rerunning with:
./mach mochitest dom/media/tests/mochitest/test_peerConnection_basicAudio.html --keep-open=false --debugger=rr --debugger-args="record -F"
And attaching with gdb, "where" gives me:
#0 mozilla::SigSysHandler (nr=0, info=0x0, void_context=0x0) at /home/mfroman/mozilla/moz-central/security/sandbox/linux/Sandbox.cpp:120
#1 <signal handler called>
#2 0x000000007000000e in ?? ()
#3 0x00007fb31124d288 in _raw_syscall () at /home/mfroman/rr/rr/src/preload/raw_syscall.S:120
#4 0x00007fb31124a012 in untraced_syscall_base (syscallno=syscallno@entry=89, a0=a0@entry=140406479660152, a1=a1@entry=140406067028008, a2=a2@entry=99, a3=a3@entry=0,
a4=a4@entry=0, a5=0, syscall_instruction=0x7000000c) at /home/mfroman/rr/rr/src/preload/preload.c:334
#5 0x00007fb31124bf5d in sys_readlink (call=0x7fb2d5ffdfb0) at /home/mfroman/rr/rr/src/preload/preload.c:1893
#6 syscall_hook_internal (call=0x7fb2d5ffdfb0) at /home/mfroman/rr/rr/src/preload/preload.c:2391
#7 syscall_hook (call=0x7fb2d5ffdfb0) at /home/mfroman/rr/rr/src/preload/preload.c:2443
#8 0x00007fb31124d2b2 in _syscall_hook_trampoline () at /home/mfroman/rr/rr/src/preload/syscall_hook.S:188
#9 0x00007fb31124d2d7 in _syscall_hook_trampoline_48_3d_01_f0_ff_ff () at /home/mfroman/rr/rr/src/preload/syscall_hook.S:249
#10 0x00007fb3055efe4d in readlink () at ../sysdeps/unix/syscall-template.S:84
#11 0x00007fb2ee551885 in pa_readlink () from /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-8.0.so
#12 0x00007fb2ee545e1c in pa_get_binary_name () from /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-8.0.so
#13 0x00007fb2ee54ffc2 in pa_get_binary_name_malloc () from /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-8.0.so
#14 0x00007fb2ee567ca2 in pa_init_proplist () from /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-8.0.so
#15 0x00007fb2ee9c25e2 in ?? () from /usr/lib/x86_64-linux-gnu/libpulse.so.0
#16 0x00007fb2ee565ae1 in ?? () from /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-8.0.so
#17 0x00007fb2ee565e6b in pa_pdispatch_run () from /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-8.0.so
#18 0x00007fb2ee9bff2e in ?? () from /usr/lib/x86_64-linux-gnu/libpulse.so.0
#19 0x00007fb2ee5686cf in ?? () from /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-8.0.so
#20 0x00007fb2ee56ad84 in ?? () from /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-8.0.so
#21 0x00007fb2ee9d4cb0 in pa_mainloop_dispatch () from /usr/lib/x86_64-linux-gnu/libpulse.so.0
#22 0x00007fb2ee9d50bc in pa_mainloop_iterate () from /usr/lib/x86_64-linux-gnu/libpulse.so.0
#23 0x00007fb2ee9d5160 in pa_mainloop_run () from /usr/lib/x86_64-linux-gnu/libpulse.so.0
#24 0x00007fb2ee9e3149 in ?? () from /usr/lib/x86_64-linux-gnu/libpulse.so.0
#25 0x00007fb2ee57b678 in ?? () from /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-8.0.so
#26 0x00007fb31103370a in start_thread (arg=0x7fb2d67fe700) at pthread_create.c:333
#27 0x00007fb3055fe82d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109
If there is additional info you'd like, please let me know!
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
dminor commentedon Nov 7, 2016
This reproduces for me on Ubuntu 16.04 with rr 4.4.0 (pulled and rebuilt this morning).
mjfroman commentedon Nov 7, 2016
To add a small bit of additional info:
dom/media/tests/mochitest/test_peerConnection_basicVideo.html records just fine.
dom/media/tests/mochitest/test_peerConnection_basicAudioVideo.html does not.
This is maybe specific to audio-related tests?
khuey commentedon Nov 7, 2016
The relevant difference may be that we're on a PulseAudio thread here. Perhaps that causes Firefox's sandbox code to behave differently.
khuey commentedon Nov 7, 2016
@rocallahan do you want to take a look at this one? I don't have any good ideas :/
rocallahan commentedon Nov 7, 2016
Looking. It reproduces in Fedora 24 so it looks like some Firefox change caused this.
rocallahan commentedon Nov 8, 2016
It's something to do with the way signals are injected. Here's a log with some instrumentation. The "blocked signals = ..." lines report the kernel signal mask as reported by
/proc/<pid>/status.This matches rr's mask.
We decide to send a SIGSYS because we think the task is not in a signal-stop. I'm not sure why in this case, since we should still be in the SIGSYS stop. This needs investigation.
Having sent the signal, we now resume-singlestep hoping to get the signal-delivery-stop.
We got it, but we're in the XXX khuey block where a SIGTRAP is being delivered for unknown reasons and the kernel has unblocked SIGTRAP!
rocallahan commentedon Nov 8, 2016
So it's time to figure out why we're getting that SIGTRAP.
rocallahan commentedon Nov 8, 2016
That's because we synthesize the SIGSYS on behalf of a seccomp filter.
khuey commentedon Nov 8, 2016
(IIRC) That SIGTRAP happens every time we synthesize the seccomp filter signal though. And this doesn't normally trip the signal mask assertion.
rocallahan commentedon Nov 8, 2016
We certainly don't always get a
SIGTRAP. A simple testcase shows us getting aSIGSYSwhen we inject aSIGSYS, as expected.rocallahan commentedon Nov 8, 2016
I'll need to do more work to confirm this, but I think the reason the assertion trips in this case and not others is that generally threads in the sandbox aren't trying to block
SIGTRAP, so when they trigger theSIGTRAPthat's harmless. But the Pulseaudio thread does blockSIGTRAP(along with every other signal it can possibly block).khuey commentedon Nov 8, 2016
Yeah, that would make more sense.
rocallahan commentedon Nov 8, 2016
We already know of cases where the kernel decides it really needs to deliver a signal and unblocks that signal if it's currently blocked, and I suspect that's what's happening here.
rocallahan commentedon Nov 8, 2016
The siginfo for the
SIGTRAPis{signo:SIGTRAP,errno:SUCCESS,code:TRAP_BRKPT,addr:0x7000000e}. That's amusing.rocallahan commentedon Nov 8, 2016
TRAP_BRKPTonly occurs twice for x86 in the kernel sources. One of them isget_si_codecalled fromdo_debugfor a hardware-triggered debug-register trap. My guess is we're not hitting this one, there's no reason to and hardware singlestepping would causeTRAP_TRACEinstead. The other isuser_single_step_siginfocalled fromtracehook_report_syscall_exitwhich is called fromsyscall_slow_exit_workwhen we singlestep out of a syscall --- this is theSIGTRAPyou get when you singlestep-exit from a syscall. The latter seems more probably but I'm not sure...rocallahan commentedon Nov 8, 2016
What I would expect to happen in the kernel here is that we're in the
PTRACE_EVENT_SECCOMPstop, we send a signal so that there's aSIGSYSqueued for the tracee, then we do thePTRACE_SINGLESTEPwhich resumes execution along the skip-syscall path. This should lead tosyscall_return_slowpathwhich (because we haveTIF_SINGLESTEP) callssyscall_slow_exit_workwhich callstracehook_report_syscall_exitwhich queues aSIGTRAP. Then inexit_to_usermode_loopwe dequeue a signal, andnext_signalshould choose the lowest-numbered signal, in this caseSIGTRAP. But obviously that's not normally what happens. Hmm...rocallahan commentedon Nov 8, 2016
Ah, I can reproduce this in a small testcase now --- it happens when we synthesize a
SIGSYSfor an untraced syscall.For traced syscalls the synthetic
SIGSYSworks because we exit the syscall viaPTRACE_SYSCALLbefore trying to deliver theSIGSYS, sotracehook_report_syscall_exitis called withstep=0. While in that syscall-exit ptrace-stop, rr sends theSIGSYSwhich is then reported via the ptrace signal-stop while the tracee is inexit_to_usermode_loop. When wePTRACE_SINGLESTEPfrom that signal-stop, noSIGTRAPis generated, we just transition to the signal handler. (I don't know exactly how that works but rr has depended on that forever.)For untraced syscalls we aren't exiting the syscall via
PTRACE_SYSCALL(because we don't need to normally), so we're trying to deliver our syntheticSIGSYSdirectly in the seccomp ptrace-stop. We send the signal and do aPTRACE_SINGLESTEPand from the seccomp ptrace-stop that triggers aSIGTRAP.I'll get some sleep and look more into this tomorrow.
mjfroman commentedon Nov 10, 2016
Thank you! Just verified it is fixed here.