xref: /aosp_15_r20/external/ltp/testcases/cve/cve-2015-3290.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later
2*49cdfc7eSAndroid Build Coastguard Worker /*
3*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (c) 2017 Pavel Boldin <[email protected]>
4*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (c) 2018-2022 Linux Test Project
5*49cdfc7eSAndroid Build Coastguard Worker  */
6*49cdfc7eSAndroid Build Coastguard Worker 
7*49cdfc7eSAndroid Build Coastguard Worker /*
8*49cdfc7eSAndroid Build Coastguard Worker 
9*49cdfc7eSAndroid Build Coastguard Worker NOTE: rather than checking for full nested NMI exploitation we simply check
10*49cdfc7eSAndroid Build Coastguard Worker that the NMI stack state can be corrupted with this code.
11*49cdfc7eSAndroid Build Coastguard Worker 
12*49cdfc7eSAndroid Build Coastguard Worker http://www.openwall.com/lists/oss-security/2015/08/04/8
13*49cdfc7eSAndroid Build Coastguard Worker 
14*49cdfc7eSAndroid Build Coastguard Worker > +++++ CVE-2015-3290 +++++
15*49cdfc7eSAndroid Build Coastguard Worker >
16*49cdfc7eSAndroid Build Coastguard Worker > High impact NMI bug on x86_64 systems 3.13 and newer, embargoed.  Also fixed
17*49cdfc7eSAndroid Build Coastguard Worker by:
18*49cdfc7eSAndroid Build Coastguard Worker >
19*49cdfc7eSAndroid Build Coastguard Worker > https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9b6e6a8334d56354853f9c255d1395c2ba570e0a
20*49cdfc7eSAndroid Build Coastguard Worker >
21*49cdfc7eSAndroid Build Coastguard Worker > The other fix (synchronous modify_ldt) does *not* fix CVE-2015-3290.
22*49cdfc7eSAndroid Build Coastguard Worker >
23*49cdfc7eSAndroid Build Coastguard Worker > You can mitigate CVE-2015-3290 by blocking modify_ldt or
24*49cdfc7eSAndroid Build Coastguard Worker > perf_event_open using seccomp.  A fully-functional, portable, reliable
25*49cdfc7eSAndroid Build Coastguard Worker > exploit is privately available and will be published in a week or two.
26*49cdfc7eSAndroid Build Coastguard Worker > *Patch your systems*
27*49cdfc7eSAndroid Build Coastguard Worker 
28*49cdfc7eSAndroid Build Coastguard Worker And here's a real advisory:
29*49cdfc7eSAndroid Build Coastguard Worker 
30*49cdfc7eSAndroid Build Coastguard Worker If an NMI returns via espfix64 and is interrupted during espfix64 setup
31*49cdfc7eSAndroid Build Coastguard Worker by another NMI, the return state is corrupt.  This is exploitable for
32*49cdfc7eSAndroid Build Coastguard Worker reliable privilege escalation on any Linux x86_64 system in which
33*49cdfc7eSAndroid Build Coastguard Worker untrusted code can arrange for espfix64 to be invoked and for NMIs to be
34*49cdfc7eSAndroid Build Coastguard Worker nested.
35*49cdfc7eSAndroid Build Coastguard Worker 
36*49cdfc7eSAndroid Build Coastguard Worker Glossing over a lot of details, the basic structure of Linux' nested NMI
37*49cdfc7eSAndroid Build Coastguard Worker handling is:
38*49cdfc7eSAndroid Build Coastguard Worker 
39*49cdfc7eSAndroid Build Coastguard Worker nmi_handler:
40*49cdfc7eSAndroid Build Coastguard Worker     if (in_nmi) {
41*49cdfc7eSAndroid Build Coastguard Worker 	nmi_latched = true;
42*49cdfc7eSAndroid Build Coastguard Worker 	return;
43*49cdfc7eSAndroid Build Coastguard Worker     }
44*49cdfc7eSAndroid Build Coastguard Worker     in_nmi = true;
45*49cdfc7eSAndroid Build Coastguard Worker     handle the nmi;
46*49cdfc7eSAndroid Build Coastguard Worker     atomically (this is magic):
47*49cdfc7eSAndroid Build Coastguard Worker 	if (nmi_latched) {
48*49cdfc7eSAndroid Build Coastguard Worker 	    nmi_latched = false;
49*49cdfc7eSAndroid Build Coastguard Worker 	    start over;
50*49cdfc7eSAndroid Build Coastguard Worker 	} else {
51*49cdfc7eSAndroid Build Coastguard Worker 	    in_nmi = false;
52*49cdfc7eSAndroid Build Coastguard Worker 	    return and unmask NMIs;
53*49cdfc7eSAndroid Build Coastguard Worker 	}
54*49cdfc7eSAndroid Build Coastguard Worker 
55*49cdfc7eSAndroid Build Coastguard Worker Alas, on x86_64, there is no reasonable way to block NMIs to run the
56*49cdfc7eSAndroid Build Coastguard Worker atomic part of that pseudocode atomically.  Instead, the entire atomic
57*49cdfc7eSAndroid Build Coastguard Worker piece is implemented by the single instruction IRET.
58*49cdfc7eSAndroid Build Coastguard Worker 
59*49cdfc7eSAndroid Build Coastguard Worker But x86_64 is more broken than just that.  The IRET instruction does not
60*49cdfc7eSAndroid Build Coastguard Worker restore register state correctly [1] when returning to a 16-bit stack
61*49cdfc7eSAndroid Build Coastguard Worker segment.  x86_64 has a complicated workaround called espfix64.  If
62*49cdfc7eSAndroid Build Coastguard Worker espfix64 is invoked on return, a well-behaved IRET is emulated by a
63*49cdfc7eSAndroid Build Coastguard Worker complicated scheme that involves manually switching stacks.  During the
64*49cdfc7eSAndroid Build Coastguard Worker stack switch, there is a window of approximately 19 instructions between
65*49cdfc7eSAndroid Build Coastguard Worker the start of espfix64's access to the original stack and when espfix64
66*49cdfc7eSAndroid Build Coastguard Worker is done with the original stack.  If a nested NMI occurs during this
67*49cdfc7eSAndroid Build Coastguard Worker window, then the atomic part of the basic nested NMI algorithm is
68*49cdfc7eSAndroid Build Coastguard Worker observably non-atomic.
69*49cdfc7eSAndroid Build Coastguard Worker 
70*49cdfc7eSAndroid Build Coastguard Worker Depending on exactly where in this window the nested NMI hits, the
71*49cdfc7eSAndroid Build Coastguard Worker results vary.  Most nested NMIs will corrupt the return context and
72*49cdfc7eSAndroid Build Coastguard Worker crash the calling process.  Some are harmless except that the nested NMI
73*49cdfc7eSAndroid Build Coastguard Worker gets ignored.  There is a two-instruction window in which the return
74*49cdfc7eSAndroid Build Coastguard Worker context ends up with user-controlled RIP and CS set to __KERNEL_CS.
75*49cdfc7eSAndroid Build Coastguard Worker 
76*49cdfc7eSAndroid Build Coastguard Worker A careful exploit (attached) can recover from all the crashy failures
77*49cdfc7eSAndroid Build Coastguard Worker and can regenerate a valid *privileged* state if a nested NMI occurs
78*49cdfc7eSAndroid Build Coastguard Worker during the two-instruction window.  This exploit appears to work
79*49cdfc7eSAndroid Build Coastguard Worker reasonably quickly across a fairly wide range of Linux versions.
80*49cdfc7eSAndroid Build Coastguard Worker 
81*49cdfc7eSAndroid Build Coastguard Worker If you have SMEP, this exploit is likely to panic the system.  Writing
82*49cdfc7eSAndroid Build Coastguard Worker a usable exploit against a SMEP system would be considerably more
83*49cdfc7eSAndroid Build Coastguard Worker challenging, but it's surely possible.
84*49cdfc7eSAndroid Build Coastguard Worker 
85*49cdfc7eSAndroid Build Coastguard Worker Measures like UDEREF are unlikely to help, because this bug is outside
86*49cdfc7eSAndroid Build Coastguard Worker any region that can be protected using paging or segmentation tricks.
87*49cdfc7eSAndroid Build Coastguard Worker However, recent grsecurity kernels seem to forcibly disable espfix64, so
88*49cdfc7eSAndroid Build Coastguard Worker they're not vulnerable in the first place.
89*49cdfc7eSAndroid Build Coastguard Worker 
90*49cdfc7eSAndroid Build Coastguard Worker A couple of notes:
91*49cdfc7eSAndroid Build Coastguard Worker 
92*49cdfc7eSAndroid Build Coastguard Worker   - This exploit's payload just prints the text "CPL0".  The exploit
93*49cdfc7eSAndroid Build Coastguard Worker     will keep going after printing CPL0 so you can enjoy seeing the
94*49cdfc7eSAndroid Build Coastguard Worker     frequency with which it wins.  Interested parties could easily
95*49cdfc7eSAndroid Build Coastguard Worker     write different payloads.  I doubt that any existing exploit
96*49cdfc7eSAndroid Build Coastguard Worker     mitigation techniques would be useful against this type of
97*49cdfc7eSAndroid Build Coastguard Worker     attack.
98*49cdfc7eSAndroid Build Coastguard Worker 
99*49cdfc7eSAndroid Build Coastguard Worker   - If you are using a kernel older than v4.1, a 64-bit build of the
100*49cdfc7eSAndroid Build Coastguard Worker     exploit will trigger a signal handling bug and crash.  Defenders
101*49cdfc7eSAndroid Build Coastguard Worker     should not rejoice, because the exploit works fine when build
102*49cdfc7eSAndroid Build Coastguard Worker     as a 32-bit binary or (so I'm told) as an x32 binary.
103*49cdfc7eSAndroid Build Coastguard Worker 
104*49cdfc7eSAndroid Build Coastguard Worker   - This is the first exploit I've ever written that contains genuine
105*49cdfc7eSAndroid Build Coastguard Worker     hexadecimal code.  The more assembly-minded among you can have
106*49cdfc7eSAndroid Build Coastguard Worker     fun figuring out why :)
107*49cdfc7eSAndroid Build Coastguard Worker 
108*49cdfc7eSAndroid Build Coastguard Worker [1] By "correctly", I mean that the register state ends up different
109*49cdfc7eSAndroid Build Coastguard Worker from that which was saved in the stack frame, not that the
110*49cdfc7eSAndroid Build Coastguard Worker implementation doesn't match the spec in the microcode author's minds.
111*49cdfc7eSAndroid Build Coastguard Worker The spec is simply broken (differently on AMD and Intel hardware,
112*49cdfc7eSAndroid Build Coastguard Worker perhaps unsurprisingly.)
113*49cdfc7eSAndroid Build Coastguard Worker 
114*49cdfc7eSAndroid Build Coastguard Worker --Andy
115*49cdfc7eSAndroid Build Coastguard Worker */
116*49cdfc7eSAndroid Build Coastguard Worker 
117*49cdfc7eSAndroid Build Coastguard Worker #include "config.h"
118*49cdfc7eSAndroid Build Coastguard Worker #include "tst_test.h"
119*49cdfc7eSAndroid Build Coastguard Worker #include "tst_timer.h"
120*49cdfc7eSAndroid Build Coastguard Worker 
121*49cdfc7eSAndroid Build Coastguard Worker #if defined(__x86_64__) || defined(__i386__)
122*49cdfc7eSAndroid Build Coastguard Worker 
123*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
124*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
125*49cdfc7eSAndroid Build Coastguard Worker #include <inttypes.h>
126*49cdfc7eSAndroid Build Coastguard Worker #include <asm/ldt.h>
127*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
128*49cdfc7eSAndroid Build Coastguard Worker #include <sys/syscall.h>
129*49cdfc7eSAndroid Build Coastguard Worker #include <setjmp.h>
130*49cdfc7eSAndroid Build Coastguard Worker #include <signal.h>
131*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
132*49cdfc7eSAndroid Build Coastguard Worker #include <sys/wait.h>
133*49cdfc7eSAndroid Build Coastguard Worker #include <linux/perf_event.h>
134*49cdfc7eSAndroid Build Coastguard Worker 
135*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/syscalls.h"
136*49cdfc7eSAndroid Build Coastguard Worker #include "tst_safe_pthread.h"
137*49cdfc7eSAndroid Build Coastguard Worker 
138*49cdfc7eSAndroid Build Coastguard Worker /* Abstractions for some 32-bit vs 64-bit differences. */
139*49cdfc7eSAndroid Build Coastguard Worker #ifdef __x86_64__
140*49cdfc7eSAndroid Build Coastguard Worker # define REG_IP REG_RIP
141*49cdfc7eSAndroid Build Coastguard Worker # define REG_SP REG_RSP
142*49cdfc7eSAndroid Build Coastguard Worker # define REG_AX REG_RAX
143*49cdfc7eSAndroid Build Coastguard Worker 
144*49cdfc7eSAndroid Build Coastguard Worker struct selectors {
145*49cdfc7eSAndroid Build Coastguard Worker 	unsigned short cs, gs, fs, ss;
146*49cdfc7eSAndroid Build Coastguard Worker };
147*49cdfc7eSAndroid Build Coastguard Worker 
148*49cdfc7eSAndroid Build Coastguard Worker LTP_ATTRIBUTE_UNUSED
ssptr(ucontext_t * ctx)149*49cdfc7eSAndroid Build Coastguard Worker static unsigned short *ssptr(ucontext_t *ctx)
150*49cdfc7eSAndroid Build Coastguard Worker {
151*49cdfc7eSAndroid Build Coastguard Worker 	struct selectors *sels = (void *)&ctx->uc_mcontext.gregs[REG_CSGSFS];
152*49cdfc7eSAndroid Build Coastguard Worker 	return &sels->ss;
153*49cdfc7eSAndroid Build Coastguard Worker }
154*49cdfc7eSAndroid Build Coastguard Worker 
155*49cdfc7eSAndroid Build Coastguard Worker LTP_ATTRIBUTE_UNUSED
csptr(ucontext_t * ctx)156*49cdfc7eSAndroid Build Coastguard Worker static unsigned short *csptr(ucontext_t *ctx)
157*49cdfc7eSAndroid Build Coastguard Worker {
158*49cdfc7eSAndroid Build Coastguard Worker 	struct selectors *sels = (void *)&ctx->uc_mcontext.gregs[REG_CSGSFS];
159*49cdfc7eSAndroid Build Coastguard Worker 	return &sels->cs;
160*49cdfc7eSAndroid Build Coastguard Worker }
161*49cdfc7eSAndroid Build Coastguard Worker #else
162*49cdfc7eSAndroid Build Coastguard Worker # define REG_IP  REG_EIP
163*49cdfc7eSAndroid Build Coastguard Worker # define REG_SP  REG_ESP
164*49cdfc7eSAndroid Build Coastguard Worker # define REG_AX  REG_EAX
165*49cdfc7eSAndroid Build Coastguard Worker # define REG_CR2 (REG_SS + 3)
166*49cdfc7eSAndroid Build Coastguard Worker 
167*49cdfc7eSAndroid Build Coastguard Worker LTP_ATTRIBUTE_UNUSED
ssptr(ucontext_t * ctx)168*49cdfc7eSAndroid Build Coastguard Worker static greg_t *ssptr(ucontext_t *ctx)
169*49cdfc7eSAndroid Build Coastguard Worker {
170*49cdfc7eSAndroid Build Coastguard Worker 	return &ctx->uc_mcontext.gregs[REG_SS];
171*49cdfc7eSAndroid Build Coastguard Worker }
172*49cdfc7eSAndroid Build Coastguard Worker 
173*49cdfc7eSAndroid Build Coastguard Worker LTP_ATTRIBUTE_UNUSED
csptr(ucontext_t * ctx)174*49cdfc7eSAndroid Build Coastguard Worker static greg_t *csptr(ucontext_t *ctx)
175*49cdfc7eSAndroid Build Coastguard Worker {
176*49cdfc7eSAndroid Build Coastguard Worker 	return &ctx->uc_mcontext.gregs[REG_CS];
177*49cdfc7eSAndroid Build Coastguard Worker }
178*49cdfc7eSAndroid Build Coastguard Worker #endif
179*49cdfc7eSAndroid Build Coastguard Worker 
180*49cdfc7eSAndroid Build Coastguard Worker static volatile long expected_rsp;
181*49cdfc7eSAndroid Build Coastguard Worker static int running = 1;
182*49cdfc7eSAndroid Build Coastguard Worker 
set_ldt(void)183*49cdfc7eSAndroid Build Coastguard Worker static void set_ldt(void)
184*49cdfc7eSAndroid Build Coastguard Worker {
185*49cdfc7eSAndroid Build Coastguard Worker 	/* Boring 16-bit data segment. */
186*49cdfc7eSAndroid Build Coastguard Worker 	const struct user_desc data_desc = {
187*49cdfc7eSAndroid Build Coastguard Worker 		.entry_number    = 0,
188*49cdfc7eSAndroid Build Coastguard Worker 		.base_addr       = 0,
189*49cdfc7eSAndroid Build Coastguard Worker 		.limit	   = 0xfffff,
190*49cdfc7eSAndroid Build Coastguard Worker 		.seg_32bit       = 0,
191*49cdfc7eSAndroid Build Coastguard Worker 		.contents	= 0, /* Data, expand-up */
192*49cdfc7eSAndroid Build Coastguard Worker 		.read_exec_only  = 0,
193*49cdfc7eSAndroid Build Coastguard Worker 		.limit_in_pages  = 0,
194*49cdfc7eSAndroid Build Coastguard Worker 		.seg_not_present = 0,
195*49cdfc7eSAndroid Build Coastguard Worker 		.useable	 = 0
196*49cdfc7eSAndroid Build Coastguard Worker 	};
197*49cdfc7eSAndroid Build Coastguard Worker 
198*49cdfc7eSAndroid Build Coastguard Worker 	TEST((int)tst_syscall(__NR_modify_ldt, 1, &data_desc,
199*49cdfc7eSAndroid Build Coastguard Worker 		sizeof(data_desc)));
200*49cdfc7eSAndroid Build Coastguard Worker 	if (TST_RET == -EINVAL) {
201*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TCONF | TRERRNO,
202*49cdfc7eSAndroid Build Coastguard Worker 			"modify_ldt: 16-bit data segments are probably disabled");
203*49cdfc7eSAndroid Build Coastguard Worker 	} else if (TST_RET != 0) {
204*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK | TRERRNO, "modify_ldt");
205*49cdfc7eSAndroid Build Coastguard Worker 	}
206*49cdfc7eSAndroid Build Coastguard Worker }
207*49cdfc7eSAndroid Build Coastguard Worker 
try_corrupt_stack(unsigned short orig_ss)208*49cdfc7eSAndroid Build Coastguard Worker static void try_corrupt_stack(unsigned short orig_ss)
209*49cdfc7eSAndroid Build Coastguard Worker {
210*49cdfc7eSAndroid Build Coastguard Worker #ifdef __x86_64__
211*49cdfc7eSAndroid Build Coastguard Worker 	asm volatile (
212*49cdfc7eSAndroid Build Coastguard Worker 	      /* A small puzzle for the curious reader. */
213*49cdfc7eSAndroid Build Coastguard Worker 	      "mov    $2048, %%rbp    \n\t"
214*49cdfc7eSAndroid Build Coastguard Worker 
215*49cdfc7eSAndroid Build Coastguard Worker 	      /* Save rsp for diagnostics */
216*49cdfc7eSAndroid Build Coastguard Worker 	      "mov    %%rsp, %[expected_rsp] \n\t"
217*49cdfc7eSAndroid Build Coastguard Worker 
218*49cdfc7eSAndroid Build Coastguard Worker 	      /*
219*49cdfc7eSAndroid Build Coastguard Worker 	       * Let 'er rip.
220*49cdfc7eSAndroid Build Coastguard Worker 	       */
221*49cdfc7eSAndroid Build Coastguard Worker 	      "mov    %[ss], %%ss \n\t"   /* begin corruption */
222*49cdfc7eSAndroid Build Coastguard Worker 	      "movl   $1000, %%edx    \n\t"
223*49cdfc7eSAndroid Build Coastguard Worker 	      "1:  decl   %%edx       \n\t"
224*49cdfc7eSAndroid Build Coastguard Worker 	      "jnz    1b      \n\t"
225*49cdfc7eSAndroid Build Coastguard Worker 	      "mov    %%ss, %%eax \n\t"   /* grab SS to display */
226*49cdfc7eSAndroid Build Coastguard Worker 
227*49cdfc7eSAndroid Build Coastguard Worker 	      /* Did we enter CPL0? */
228*49cdfc7eSAndroid Build Coastguard Worker 	      "mov    %%cs, %%dx  \n\t"
229*49cdfc7eSAndroid Build Coastguard Worker 	      "testw  $3, %%dx    \n\t"
230*49cdfc7eSAndroid Build Coastguard Worker 	      "jnz    2f      \n\t"
231*49cdfc7eSAndroid Build Coastguard Worker 	      "leaq   3f(%%rip), %%rcx  \n\t"
232*49cdfc7eSAndroid Build Coastguard Worker 	      "movl   $0x200, %%r11d  \n\t"
233*49cdfc7eSAndroid Build Coastguard Worker 	      "sysretq	\n\t"
234*49cdfc7eSAndroid Build Coastguard Worker 	      "2:	     \n\t"
235*49cdfc7eSAndroid Build Coastguard Worker 
236*49cdfc7eSAndroid Build Coastguard Worker 	      /*
237*49cdfc7eSAndroid Build Coastguard Worker 	       * Stop further corruption.  We need to check CPL
238*49cdfc7eSAndroid Build Coastguard Worker 	       * first because we need RPL == CPL.
239*49cdfc7eSAndroid Build Coastguard Worker 	       */
240*49cdfc7eSAndroid Build Coastguard Worker 	      "mov    %[orig_ss], %%ss \n\t"  /* end corruption */
241*49cdfc7eSAndroid Build Coastguard Worker 
242*49cdfc7eSAndroid Build Coastguard Worker 	      "subq   $128, %%rsp \n\t"
243*49cdfc7eSAndroid Build Coastguard Worker 	      "pushfq	 \n\t"
244*49cdfc7eSAndroid Build Coastguard Worker 	      "testl  $(1<<9),(%%rsp)   \n\t"
245*49cdfc7eSAndroid Build Coastguard Worker 	      "addq   $136, %%rsp \n\t"
246*49cdfc7eSAndroid Build Coastguard Worker 	      "jz 3f      \n\t"
247*49cdfc7eSAndroid Build Coastguard Worker 	      "cmpl   %[ss], %%eax    \n\t"
248*49cdfc7eSAndroid Build Coastguard Worker 	      "je 4f      \n\t"
249*49cdfc7eSAndroid Build Coastguard Worker 	      "3:  int3	   \n\t"
250*49cdfc7eSAndroid Build Coastguard Worker 	      "4:	     \n\t"
251*49cdfc7eSAndroid Build Coastguard Worker 	      : [expected_rsp] "=m" (expected_rsp)
252*49cdfc7eSAndroid Build Coastguard Worker 	      : [ss] "r" (0x7), [orig_ss] "m" (orig_ss)
253*49cdfc7eSAndroid Build Coastguard Worker 		 : "rax", "rcx", "rdx", "rbp", "r11", "flags"
254*49cdfc7eSAndroid Build Coastguard Worker 	);
255*49cdfc7eSAndroid Build Coastguard Worker #else
256*49cdfc7eSAndroid Build Coastguard Worker 	asm volatile (
257*49cdfc7eSAndroid Build Coastguard Worker 	      /* A small puzzle for the curious reader. */
258*49cdfc7eSAndroid Build Coastguard Worker 	      "mov    %%ebp, %%esi    \n\t"
259*49cdfc7eSAndroid Build Coastguard Worker 	      "mov    $2048, %%ebp    \n\t"
260*49cdfc7eSAndroid Build Coastguard Worker 
261*49cdfc7eSAndroid Build Coastguard Worker 	      /* Save rsp for diagnostics */
262*49cdfc7eSAndroid Build Coastguard Worker 	      "mov    %%esp, %[expected_rsp] \n\t"
263*49cdfc7eSAndroid Build Coastguard Worker 
264*49cdfc7eSAndroid Build Coastguard Worker 	      /*
265*49cdfc7eSAndroid Build Coastguard Worker 	       * Let 'er rip.
266*49cdfc7eSAndroid Build Coastguard Worker 	       */
267*49cdfc7eSAndroid Build Coastguard Worker 	      "mov    %[ss], %%ss \n\t"   /* begin corruption */
268*49cdfc7eSAndroid Build Coastguard Worker 	      "movl   $1000, %%edx    \n\t"
269*49cdfc7eSAndroid Build Coastguard Worker 	      "1:  .byte 0xff, 0xca   \n\t"   /* decl %edx */
270*49cdfc7eSAndroid Build Coastguard Worker 	      "jnz    1b      \n\t"
271*49cdfc7eSAndroid Build Coastguard Worker 	      "mov    %%ss, %%eax \n\t"   /* grab SS to display */
272*49cdfc7eSAndroid Build Coastguard Worker 
273*49cdfc7eSAndroid Build Coastguard Worker 	      /* Did we enter CPL0? */
274*49cdfc7eSAndroid Build Coastguard Worker 	      "mov    %%cs, %%dx  \n\t"
275*49cdfc7eSAndroid Build Coastguard Worker 	      "testw  $3, %%dx    \n\t"
276*49cdfc7eSAndroid Build Coastguard Worker 	      "jnz    2f      \n\t"
277*49cdfc7eSAndroid Build Coastguard Worker 	      ".code64	\n\t"
278*49cdfc7eSAndroid Build Coastguard Worker 	      "leaq   3f(%%rip), %%rcx \n\t"
279*49cdfc7eSAndroid Build Coastguard Worker 	      "movl   $0x200, %%r11d  \n\t"
280*49cdfc7eSAndroid Build Coastguard Worker 	      "sysretl	\n\t"
281*49cdfc7eSAndroid Build Coastguard Worker 	      ".code32	\n\t"
282*49cdfc7eSAndroid Build Coastguard Worker 	      "2:	     \n\t"
283*49cdfc7eSAndroid Build Coastguard Worker 
284*49cdfc7eSAndroid Build Coastguard Worker 	      /*
285*49cdfc7eSAndroid Build Coastguard Worker 	       * Stop further corruption.  We need to check CPL
286*49cdfc7eSAndroid Build Coastguard Worker 	       * first because we need RPL == CPL.
287*49cdfc7eSAndroid Build Coastguard Worker 	       */
288*49cdfc7eSAndroid Build Coastguard Worker 	      "mov    %[orig_ss], %%ss \n\t"  /* end corruption */
289*49cdfc7eSAndroid Build Coastguard Worker 
290*49cdfc7eSAndroid Build Coastguard Worker 	      "pushf	  \n\t"
291*49cdfc7eSAndroid Build Coastguard Worker 	      "testl  $(1<<9),(%%esp)   \n\t"
292*49cdfc7eSAndroid Build Coastguard Worker 	      "addl   $4, %%esp   \n\t"
293*49cdfc7eSAndroid Build Coastguard Worker 	      "jz 3f      \n\t"
294*49cdfc7eSAndroid Build Coastguard Worker 	      "cmpl   %[ss], %%eax    \n\t"
295*49cdfc7eSAndroid Build Coastguard Worker 	      "je 4f      \n\t"
296*49cdfc7eSAndroid Build Coastguard Worker 	      "3:  int3	   \n\t"
297*49cdfc7eSAndroid Build Coastguard Worker 	      "4:  mov %%esi, %%ebp   \n\t"
298*49cdfc7eSAndroid Build Coastguard Worker 	      : [expected_rsp] "=m" (expected_rsp)
299*49cdfc7eSAndroid Build Coastguard Worker 	      : [ss] "r" (0x7), [orig_ss] "m" (orig_ss)
300*49cdfc7eSAndroid Build Coastguard Worker 		 : "eax", "ecx", "edx", "esi", "flags"
301*49cdfc7eSAndroid Build Coastguard Worker 	);
302*49cdfc7eSAndroid Build Coastguard Worker #endif
303*49cdfc7eSAndroid Build Coastguard Worker }
304*49cdfc7eSAndroid Build Coastguard Worker 
perf_event_open(struct perf_event_attr * hw_event,pid_t pid,int cpu,int group_fd,unsigned long flags)305*49cdfc7eSAndroid Build Coastguard Worker static int perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
306*49cdfc7eSAndroid Build Coastguard Worker 			   int cpu, int group_fd, unsigned long flags)
307*49cdfc7eSAndroid Build Coastguard Worker {
308*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
309*49cdfc7eSAndroid Build Coastguard Worker 
310*49cdfc7eSAndroid Build Coastguard Worker 	ret = tst_syscall(__NR_perf_event_open, hw_event, pid, cpu,
311*49cdfc7eSAndroid Build Coastguard Worker 			  group_fd, flags);
312*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
313*49cdfc7eSAndroid Build Coastguard Worker }
314*49cdfc7eSAndroid Build Coastguard Worker 
315*49cdfc7eSAndroid Build Coastguard Worker static int event_mlock_kb;
316*49cdfc7eSAndroid Build Coastguard Worker static int max_sample_rate;
317*49cdfc7eSAndroid Build Coastguard Worker 
child_thread(void * arg LTP_ATTRIBUTE_UNUSED)318*49cdfc7eSAndroid Build Coastguard Worker static void *child_thread(void *arg LTP_ATTRIBUTE_UNUSED)
319*49cdfc7eSAndroid Build Coastguard Worker {
320*49cdfc7eSAndroid Build Coastguard Worker 	long niter = 0;
321*49cdfc7eSAndroid Build Coastguard Worker 	unsigned short orig_ss;
322*49cdfc7eSAndroid Build Coastguard Worker 
323*49cdfc7eSAndroid Build Coastguard Worker 	struct perf_event_attr pe = {
324*49cdfc7eSAndroid Build Coastguard Worker 		.size = sizeof(struct perf_event_attr),
325*49cdfc7eSAndroid Build Coastguard Worker 		.disabled = 0,
326*49cdfc7eSAndroid Build Coastguard Worker 		.exclude_kernel = 0,
327*49cdfc7eSAndroid Build Coastguard Worker 		.exclude_hv = 0,
328*49cdfc7eSAndroid Build Coastguard Worker 		.freq = 1,
329*49cdfc7eSAndroid Build Coastguard Worker 		.sample_type = PERF_SAMPLE_IP|PERF_SAMPLE_TID|
330*49cdfc7eSAndroid Build Coastguard Worker 			PERF_SAMPLE_TIME|PERF_SAMPLE_CALLCHAIN|
331*49cdfc7eSAndroid Build Coastguard Worker 			PERF_SAMPLE_ID|PERF_SAMPLE_PERIOD,
332*49cdfc7eSAndroid Build Coastguard Worker 	};
333*49cdfc7eSAndroid Build Coastguard Worker 	/* Workaround bug in GCC 4.4.7 (CentOS6) */
334*49cdfc7eSAndroid Build Coastguard Worker 	pe.sample_freq = max_sample_rate / 5;
335*49cdfc7eSAndroid Build Coastguard Worker 
336*49cdfc7eSAndroid Build Coastguard Worker 	struct {
337*49cdfc7eSAndroid Build Coastguard Worker 		uint32_t type;
338*49cdfc7eSAndroid Build Coastguard Worker 		uint64_t config;
339*49cdfc7eSAndroid Build Coastguard Worker 		const char *name;
340*49cdfc7eSAndroid Build Coastguard Worker 	} perf_events[] = {
341*49cdfc7eSAndroid Build Coastguard Worker 		{
342*49cdfc7eSAndroid Build Coastguard Worker 			.type = PERF_TYPE_HARDWARE,
343*49cdfc7eSAndroid Build Coastguard Worker 			.config = PERF_COUNT_HW_INSTRUCTIONS,
344*49cdfc7eSAndroid Build Coastguard Worker 			.name = "hw instructions",
345*49cdfc7eSAndroid Build Coastguard Worker 		},
346*49cdfc7eSAndroid Build Coastguard Worker 		{
347*49cdfc7eSAndroid Build Coastguard Worker 			.type = PERF_TYPE_HARDWARE,
348*49cdfc7eSAndroid Build Coastguard Worker 			.config = PERF_COUNT_HW_CACHE_REFERENCES,
349*49cdfc7eSAndroid Build Coastguard Worker 			.name = "hw cache references",
350*49cdfc7eSAndroid Build Coastguard Worker 		},
351*49cdfc7eSAndroid Build Coastguard Worker 	};
352*49cdfc7eSAndroid Build Coastguard Worker 
353*49cdfc7eSAndroid Build Coastguard Worker 	void *perf_mmaps[ARRAY_SIZE(perf_events)];
354*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int i;
355*49cdfc7eSAndroid Build Coastguard Worker 
356*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(perf_events); i++) {
357*49cdfc7eSAndroid Build Coastguard Worker 		int fd;
358*49cdfc7eSAndroid Build Coastguard Worker 
359*49cdfc7eSAndroid Build Coastguard Worker 		pe.type = perf_events[i].type;
360*49cdfc7eSAndroid Build Coastguard Worker 		pe.config = perf_events[i].config;
361*49cdfc7eSAndroid Build Coastguard Worker 
362*49cdfc7eSAndroid Build Coastguard Worker 		fd = perf_event_open(&pe, 0, -1, -1, 0);
363*49cdfc7eSAndroid Build Coastguard Worker 		if (fd == -1) {
364*49cdfc7eSAndroid Build Coastguard Worker 			if (errno == EINVAL || errno == ENOENT ||
365*49cdfc7eSAndroid Build Coastguard Worker 			    errno == EBUSY)
366*49cdfc7eSAndroid Build Coastguard Worker 				tst_brk(TCONF | TERRNO,
367*49cdfc7eSAndroid Build Coastguard Worker 					"no hardware counters");
368*49cdfc7eSAndroid Build Coastguard Worker 			else
369*49cdfc7eSAndroid Build Coastguard Worker 				tst_brk(TBROK | TERRNO, "perf_event_open");
370*49cdfc7eSAndroid Build Coastguard Worker 			/* tst_brk exits */
371*49cdfc7eSAndroid Build Coastguard Worker 		}
372*49cdfc7eSAndroid Build Coastguard Worker 
373*49cdfc7eSAndroid Build Coastguard Worker 		perf_mmaps[i] = SAFE_MMAP(NULL, event_mlock_kb * 1024,
374*49cdfc7eSAndroid Build Coastguard Worker 					  PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
375*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_CLOSE(fd);
376*49cdfc7eSAndroid Build Coastguard Worker 	}
377*49cdfc7eSAndroid Build Coastguard Worker 
378*49cdfc7eSAndroid Build Coastguard Worker 	asm volatile ("mov %%ss, %0" : "=rm" (orig_ss));
379*49cdfc7eSAndroid Build Coastguard Worker 
380*49cdfc7eSAndroid Build Coastguard Worker 	for (niter = 0; running && niter < 1000*1000*1000L; niter++) {
381*49cdfc7eSAndroid Build Coastguard Worker 
382*49cdfc7eSAndroid Build Coastguard Worker 		try_corrupt_stack(orig_ss);
383*49cdfc7eSAndroid Build Coastguard Worker 
384*49cdfc7eSAndroid Build Coastguard Worker 		/*
385*49cdfc7eSAndroid Build Coastguard Worker 		 * If we ended up with IF == 0, there's no easy way to fix
386*49cdfc7eSAndroid Build Coastguard Worker 		 * it.  Instead, make frequent syscalls to avoid hanging
387*49cdfc7eSAndroid Build Coastguard Worker 		 * the system.
388*49cdfc7eSAndroid Build Coastguard Worker 		 */
389*49cdfc7eSAndroid Build Coastguard Worker 		syscall(0x3fffffff);
390*49cdfc7eSAndroid Build Coastguard Worker 	}
391*49cdfc7eSAndroid Build Coastguard Worker 
392*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(perf_events); i++)
393*49cdfc7eSAndroid Build Coastguard Worker 		if (perf_mmaps[i] != MAP_FAILED)
394*49cdfc7eSAndroid Build Coastguard Worker 			SAFE_MUNMAP(perf_mmaps[i], 512 * 1024);
395*49cdfc7eSAndroid Build Coastguard Worker 
396*49cdfc7eSAndroid Build Coastguard Worker 	return (void *)niter;
397*49cdfc7eSAndroid Build Coastguard Worker }
398*49cdfc7eSAndroid Build Coastguard Worker 
do_child(void)399*49cdfc7eSAndroid Build Coastguard Worker static void do_child(void)
400*49cdfc7eSAndroid Build Coastguard Worker {
401*49cdfc7eSAndroid Build Coastguard Worker 	int i, ncpus;
402*49cdfc7eSAndroid Build Coastguard Worker 	pthread_t *threads;
403*49cdfc7eSAndroid Build Coastguard Worker 	long iter, total_iter = 0;
404*49cdfc7eSAndroid Build Coastguard Worker 
405*49cdfc7eSAndroid Build Coastguard Worker 	tst_res(TINFO, "attempting to corrupt nested NMI stack state");
406*49cdfc7eSAndroid Build Coastguard Worker 
407*49cdfc7eSAndroid Build Coastguard Worker 	set_ldt();
408*49cdfc7eSAndroid Build Coastguard Worker 
409*49cdfc7eSAndroid Build Coastguard Worker 	ncpus = tst_ncpus();
410*49cdfc7eSAndroid Build Coastguard Worker 	threads = SAFE_MALLOC(sizeof(*threads) * ncpus);
411*49cdfc7eSAndroid Build Coastguard Worker 
412*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < ncpus; i++)
413*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_PTHREAD_CREATE(&threads[i], NULL, child_thread, NULL);
414*49cdfc7eSAndroid Build Coastguard Worker 
415*49cdfc7eSAndroid Build Coastguard Worker 	sleep(tst_remaining_runtime());
416*49cdfc7eSAndroid Build Coastguard Worker 	running = 0;
417*49cdfc7eSAndroid Build Coastguard Worker 
418*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < ncpus; i++) {
419*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_PTHREAD_JOIN(threads[i], (void **)&iter);
420*49cdfc7eSAndroid Build Coastguard Worker 		total_iter += iter;
421*49cdfc7eSAndroid Build Coastguard Worker 	}
422*49cdfc7eSAndroid Build Coastguard Worker 	free(threads);
423*49cdfc7eSAndroid Build Coastguard Worker 
424*49cdfc7eSAndroid Build Coastguard Worker 	tst_res(TPASS, "can't corrupt nested NMI state after %ld iterations",
425*49cdfc7eSAndroid Build Coastguard Worker 		total_iter);
426*49cdfc7eSAndroid Build Coastguard Worker }
427*49cdfc7eSAndroid Build Coastguard Worker 
setup(void)428*49cdfc7eSAndroid Build Coastguard Worker static void setup(void)
429*49cdfc7eSAndroid Build Coastguard Worker {
430*49cdfc7eSAndroid Build Coastguard Worker         /*
431*49cdfc7eSAndroid Build Coastguard Worker          * According to perf_event_open's manpage, the official way of
432*49cdfc7eSAndroid Build Coastguard Worker          * knowing if perf_event_open() support is enabled is checking for
433*49cdfc7eSAndroid Build Coastguard Worker          * the existence of the file /proc/sys/kernel/perf_event_paranoid.
434*49cdfc7eSAndroid Build Coastguard Worker          */
435*49cdfc7eSAndroid Build Coastguard Worker 	if (access("/proc/sys/kernel/perf_event_paranoid", F_OK) == -1)
436*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TCONF, "Kernel doesn't have perf_event support");
437*49cdfc7eSAndroid Build Coastguard Worker 
438*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_FILE_SCANF("/proc/sys/kernel/perf_event_mlock_kb",
439*49cdfc7eSAndroid Build Coastguard Worker 			"%d", &event_mlock_kb);
440*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_FILE_SCANF("/proc/sys/kernel/perf_event_max_sample_rate",
441*49cdfc7eSAndroid Build Coastguard Worker 			"%d", &max_sample_rate);
442*49cdfc7eSAndroid Build Coastguard Worker }
443*49cdfc7eSAndroid Build Coastguard Worker 
run(void)444*49cdfc7eSAndroid Build Coastguard Worker static void run(void)
445*49cdfc7eSAndroid Build Coastguard Worker {
446*49cdfc7eSAndroid Build Coastguard Worker 	pid_t pid;
447*49cdfc7eSAndroid Build Coastguard Worker 	int status;
448*49cdfc7eSAndroid Build Coastguard Worker 
449*49cdfc7eSAndroid Build Coastguard Worker 
450*49cdfc7eSAndroid Build Coastguard Worker 	pid = SAFE_FORK();
451*49cdfc7eSAndroid Build Coastguard Worker 	if (pid == 0) {
452*49cdfc7eSAndroid Build Coastguard Worker 		do_child();
453*49cdfc7eSAndroid Build Coastguard Worker 		return;
454*49cdfc7eSAndroid Build Coastguard Worker 	}
455*49cdfc7eSAndroid Build Coastguard Worker 
456*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_WAITPID(pid, &status, 0);
457*49cdfc7eSAndroid Build Coastguard Worker 	if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV)
458*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL, "corrupted NMI stack");
459*49cdfc7eSAndroid Build Coastguard Worker 	else if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
460*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(WEXITSTATUS(status), "Propogate child status");
461*49cdfc7eSAndroid Build Coastguard Worker }
462*49cdfc7eSAndroid Build Coastguard Worker 
463*49cdfc7eSAndroid Build Coastguard Worker static struct tst_test test = {
464*49cdfc7eSAndroid Build Coastguard Worker 	.forks_child = 1,
465*49cdfc7eSAndroid Build Coastguard Worker 	.needs_root = 1,
466*49cdfc7eSAndroid Build Coastguard Worker 	.needs_checkpoints = 1,
467*49cdfc7eSAndroid Build Coastguard Worker 	.setup = setup,
468*49cdfc7eSAndroid Build Coastguard Worker 	.max_runtime = 180,
469*49cdfc7eSAndroid Build Coastguard Worker 	.test_all = run,
470*49cdfc7eSAndroid Build Coastguard Worker 	.tags = (const struct tst_tag[]) {
471*49cdfc7eSAndroid Build Coastguard Worker 		{"linux-git", "9b6e6a8334d5"},
472*49cdfc7eSAndroid Build Coastguard Worker 		{"CVE", "2015-3290"},
473*49cdfc7eSAndroid Build Coastguard Worker 		{}
474*49cdfc7eSAndroid Build Coastguard Worker 	}
475*49cdfc7eSAndroid Build Coastguard Worker };
476*49cdfc7eSAndroid Build Coastguard Worker 
477*49cdfc7eSAndroid Build Coastguard Worker #else /* defined(__x86_64__) || defined(__i386__) */
478*49cdfc7eSAndroid Build Coastguard Worker 
479*49cdfc7eSAndroid Build Coastguard Worker TST_TEST_TCONF("not (i386 or x86_64)");
480*49cdfc7eSAndroid Build Coastguard Worker 
481*49cdfc7eSAndroid Build Coastguard Worker #endif
482