On 12/10/2017 21:30, Richard Henderson wrote: > On 10/12/2017 07:35 AM, Paolo Bonzini wrote: >> Besides being more correct, arbitrarily long instruction allow the >> generation of a translation block that spans three pages. This >> confuses the generator and even allows ring 3 code to poison the >> translation block cache and inject code into other processes that are >> in guest ring 3. >> >> This is an improved (and more invasive) fix for the bug fixed in commit >> 30663fd ("tcg/i386: Check the size of instruction being translated", >> 2017-03-24). In addition to being more precise (and generating the >> right exception, which is #GP rather than #UD), it distinguishes better >> between page faults and too long instructions, as shown by this test case: >> >> #include <sys/mman.h> >> #include <string.h> >> #include <stdio.h> >> >> int main() >> { >> char *x = mmap(NULL, 8192, PROT_READ|PROT_WRITE|PROT_EXEC, >> MAP_PRIVATE|MAP_ANON, -1, 0); >> memset(x, 0x66, 4096); >> x[4096] = 0x90; >> x[4097] = 0xc3; >> char *i = x + 4096 - 15; >> mprotect(x + 4096, 4096, PROT_READ|PROT_WRITE); >> ((void(*)(void)) i) (); >> } >> >> ... which produces a #GP without the mprotect, and a #PF with it. >> >> Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> >> --- >> target/i386/translate.c | 29 ++++++++++++++++++++++------- >> 1 file changed, 22 insertions(+), 7 deletions(-) > > Reviewed-by: Richard Henderson <richard.hender...@linaro.org> > >> + if (sigsetjmp(s->jmpbuf, 0) != 0) { > > Any particular reason to use sigsetjmp(x, 0) instead of setjmp(x)? > Certainly there are no signal frames that the longjmp will pass...
sigsetjmp is used to _not_ save the signal mask. On OS X setjmp saves the signal mask by default, which is slower. Paolo