On 27 February 2014 13:20, Michael Matz <m...@suse.de> wrote: > On Wed, 26 Feb 2014, Dann Frazier wrote: >> I've narrowed down the changes that seem to prevent both types of >> segfaults to the following changes that introduce a wrapper around >> sigprocmask: >> >> https://github.com/susematz/qemu/commit/f1542ae9fe10d5a241fc2624ecaef5f0948e3472 >> https://github.com/susematz/qemu/commit/4e5e1607758841c760cda4652b0ee7a6bc6eb79d >> https://github.com/susematz/qemu/commit/63eb8d3ea58f58d5857153b0c632def1bbd05781 >> >> I'm not sure if this is a real fix or just papering over my issue -
I've cleaned up these a bit (and added a bunch of missing wrapper calls) and am testing them now. I'll post them to qemu-devel when that's done. > It's fixing the issue, but strictly speaking introduces an QoI problem. > SIGSEGV must not be controllable by the guest, it needs to be always > deliverable to qemu; that is what's fixed. > > The QoI problem introduced is that with the implementation as is, the > fiddling with SIGSEGV is detectable by the guest. E.g. if it installs a > segv handler, blocks segv, then forces a segfault, checks that it didn't > arrive, then unblocks segv and checks that it now arrives, such testcase > would be able to detect that in fact it couldn't block SIGSEGV. My rework opts to track with a flag whether SIGSEGV is blocked by the guest or not; this is fairly straightforward. > To fix also that latter part it'd need a further per-thread flag > segv_blocked_p which needs to be checked before actually delivering a > guest-directed SIGSEGV (in comparison to a qemu-directed SEGV), and > otherwise requeue it. That's made a bit complicated when the SEGV was > process-directed (not thread-directed) because in that case it needs to be > delivered as long as there's _any_ thread which has it unblocked. So > given the above undefinedness for sane uses of SEGVs it didn't seem worth > the complication of having an undetectable virtualization of SIGSEGV. I don't bother to emulate to this level though -- if we get a guest directed SIGSEGV and the target has it blocked then we assume it was a from-the-kernel SEGV (ie guest dereferenced NULL or similar) and treat it as the kernel force_sig_info() does: behave as if the default SEGV handler was installed. This seems a reasonable compromise since I assume people don't typically go around sending manual SEGVs to other processes and threads. thanks -- PMM