diff --git a/testcases/cve/cve-2015-3290.c b/testcases/cve/cve-2015-3290.c index 58585bac0a0..143c98230fb 100644 --- a/testcases/cve/cve-2015-3290.c +++ b/testcases/cve/cve-2015-3290.c @@ -218,7 +218,7 @@ static void set_ldt(void) } } -static void try_corrupt_stack(unsigned short orig_ss) +static void try_corrupt_stack(unsigned short *orig_ss) { #ifdef __x86_64__ asm volatile ( @@ -231,7 +231,8 @@ static void try_corrupt_stack(unsigned short orig_ss) /* * Let 'er rip. */ - "mov %[ss], %%ss \n\t" /* begin corruption */ + "mov %[ss], %%edx \n\t" + "mov %%edx, %%ss \n\t" /* begin corruption */ "movl $1000, %%edx \n\t" "1: decl %%edx \n\t" "jnz 1b \n\t" @@ -250,7 +251,7 @@ static void try_corrupt_stack(unsigned short orig_ss) * Stop further corruption. We need to check CPL * first because we need RPL == CPL. */ - "mov %[orig_ss], %%ss \n\t" /* end corruption */ + "mov (%[orig_ss]), %%ss \n\t" /* end corruption */ "subq $128, %%rsp \n\t" "pushfq \n\t" @@ -262,7 +263,7 @@ static void try_corrupt_stack(unsigned short orig_ss) "3: int3 \n\t" "4: \n\t" : [expected_rsp] "=m" (expected_rsp) - : [ss] "r" (0x7), [orig_ss] "m" (orig_ss) + : [ss] "n" (0x7), [orig_ss] "r" (orig_ss) : "rax", "rcx", "rdx", "rbp", "r11", "flags" ); #else @@ -277,7 +278,8 @@ static void try_corrupt_stack(unsigned short orig_ss) /* * Let 'er rip. */ - "mov %[ss], %%ss \n\t" /* begin corruption */ + "mov %[ss], %%edx \n\t" + "mov %%edx, %%ss \n\t" /* begin corruption */ "movl $1000, %%edx \n\t" "1: .byte 0xff, 0xca \n\t" /* decl %edx */ "jnz 1b \n\t" @@ -298,7 +300,7 @@ static void try_corrupt_stack(unsigned short orig_ss) * Stop further corruption. We need to check CPL * first because we need RPL == CPL. */ - "mov %[orig_ss], %%ss \n\t" /* end corruption */ + "mov (%[orig_ss]), %%ss \n\t" /* end corruption */ "pushf \n\t" "testl $(1<<9),(%%esp) \n\t" @@ -309,8 +311,8 @@ static void try_corrupt_stack(unsigned short orig_ss) "3: int3 \n\t" "4: mov %%esi, %%ebp \n\t" : [expected_rsp] "=m" (expected_rsp) - : [ss] "r" (0x7), [orig_ss] "m" (orig_ss) - : "eax", "ecx", "edx", "esi", "flags" + : [ss] "n" (0x7), [orig_ss] "r" (orig_ss) + : "eax", "ecx", "edx", "esi", "ebp", "flags" ); #endif } @@ -328,10 +330,14 @@ static int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, static int event_mlock_kb; static int max_sample_rate; -static void *child_thread(void *arg LTP_ATTRIBUTE_UNUSED) +static void *child_thread(void *arg) { + /* + * orig_ss must not be accessed via address relative to %esp, + * otherwise mov %[orig_ss], %%ss above will always segfault + */ + unsigned short *orig_ss = arg; long niter = 0; - unsigned short orig_ss; struct perf_event_attr pe = { .size = sizeof(struct perf_event_attr), @@ -388,7 +394,7 @@ static void *child_thread(void *arg LTP_ATTRIBUTE_UNUSED) SAFE_CLOSE(fd); } - asm volatile ("mov %%ss, %0" : "=rm" (orig_ss)); + asm volatile ("mov %%ss, (%0)" :: "r" (orig_ss)); for (niter = 0; running && niter < 1000*1000*1000L; niter++) { @@ -414,6 +420,7 @@ static void do_child(void) int i, ncpus; pthread_t *threads; long iter, total_iter = 0; + unsigned short *orig_ss; tst_res(TINFO, "attempting to corrupt nested NMI stack state"); @@ -421,9 +428,12 @@ static void do_child(void) ncpus = tst_ncpus(); threads = SAFE_MALLOC(sizeof(*threads) * ncpus); + orig_ss = SAFE_MALLOC(sizeof(unsigned short) * ncpus); - for (i = 0; i < ncpus; i++) - SAFE_PTHREAD_CREATE(&threads[i], NULL, child_thread, NULL); + for (i = 0; i < ncpus; i++) { + SAFE_PTHREAD_CREATE(&threads[i], NULL, child_thread, + &orig_ss[i]); + } sleep(tst_remaining_runtime()); running = 0; @@ -432,6 +442,7 @@ static void do_child(void) SAFE_PTHREAD_JOIN(threads[i], (void **)&iter); total_iter += iter; } + free(orig_ss); free(threads); tst_res(TPASS, "can't corrupt nested NMI state after %ld iterations",