aboutsummaryrefslogtreecommitdiff
path: root/memory.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2017-03-22 11:57:10 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2017-10-16 18:03:53 +0200
commitb066c5375737ad0d630196dab2a2b329515a1d00 (patch)
tree510ec6e0103118d9e1b61e7bdfeaa8940664ff3b /memory.c
parente3af7c788b73a6495eb9d94992ef11f6ad6f3c56 (diff)
target/i386: trap on instructions longer than >15 bytes
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 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 <pbonzini@redhat.com>
Diffstat (limited to 'memory.c')
0 files changed, 0 insertions, 0 deletions