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... r~