Created
December 10, 2014 09:26
-
-
Save Proteas/128a84846eda9913624a to your computer and use it in GitHub Desktop.
Race Condition
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define _GNU_SOURCE | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <sys/syscall.h> | |
#include <sched.h> | |
#include <sys/mman.h> | |
#include <string.h> | |
#include <sys/utsname.h> | |
#include <sys/mman.h> | |
#include <sched.h> | |
#include <stdint.h> | |
static unsigned long __rdtsc() | |
{ | |
unsigned long __tsc; | |
asm volatile( | |
"pushq %%rax\t\n" | |
"pushq %%rdx\t\n" | |
"xorq %%rdx, %%rdx\t\n" | |
"xorq %%rax, %%rax\t\n" | |
"rdtsc\t\n" | |
"shlq $32, %%rdx\t\n" | |
"orq %%rdx, %%rax\t\n" | |
"movq %%rax, %0\t\n" | |
"popq %%rdx\t\n" | |
"popq %%rax\t\n" | |
: "=r"(__tsc) : : "rdx", "rax" | |
); | |
return __tsc; | |
} | |
#define STACK_SIZE 8192 | |
#ifndef __fatal_errno | |
#define __fatal_errno(msg) \ | |
do { perror(msg); exit(1); } while(0) | |
#endif | |
static int start_thread(int (*f)(void *), void *arg) | |
{ | |
char *stack = calloc(1, STACK_SIZE); | |
int tid; | |
if(stack == NULL) | |
__fatal_errno("calloc"); | |
tid = clone(f, stack + STACK_SIZE - sizeof(unsigned long), | |
CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_VM, arg); | |
if (tid < 0) { | |
free(stack); | |
__fatal_errno("clone"); | |
} | |
return tid; | |
} | |
#define BufferSize (1024 * 4) | |
unsigned char align_data[BufferSize] __attribute__((aligned(4096))); | |
volatile int check, s_check, racer = 0; | |
static int racer_thread(void *useless) | |
{ | |
while(!racer); | |
unsigned long *ptr = useless; | |
*ptr = 1; | |
printf("\n------------>Seq-2\n"); | |
check = 1; | |
} | |
int main(int argc, char** argv) | |
{ | |
int fd_odirect = 0, fd_common = 0; | |
unsigned long tsc_1 = 0, tsc_2 = 0; | |
void *addr = NULL; | |
int count = 0; | |
memset(align_data, 0x0, BufferSize); | |
char *file_path = "./test.txt"; //argv[1]; | |
fd_odirect = open(file_path, O_RDWR | O_CREAT | O_DIRECT, S_IRWXU); | |
fd_common = open(file_path, O_RDWR | O_CREAT, S_IRWXU); | |
count = write(fd_odirect, align_data, BufferSize); | |
if (-1 == count) { | |
printf("failt to write to map\n"); | |
exit(-1); | |
} | |
addr = mmap(NULL, BufferSize, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd_common, 0); | |
printf("mapped address: %p\n", addr); | |
racer = check = 0; | |
s_check=check; | |
tsc_1 = __rdtsc(); | |
//sleep(1); | |
racer=1; | |
start_thread(racer_thread, addr); | |
uname((struct utsname *)addr); | |
printf("\n------------>Seq-1\n"); | |
tsc_2 = __rdtsc(); | |
unsigned long *ptr = addr; | |
unsigned long value = *ptr; | |
printf("\n------------>Seq-3\n"); | |
munmap(addr, BufferSize); | |
if(check != s_check) { | |
printf("[**] check Changed Across uname() before=%d, after=%d\n", s_check, check); | |
} | |
else { | |
printf("[!!] check unchanged: Race Failed\n"); | |
printf("[**] syscall accessing \"racer buffer\": TSC diff: %ld\n", tsc_2 - tsc_1); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
fineshed