Skip to content

Instantly share code, notes, and snippets.

@Proteas
Created December 10, 2014 09:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Proteas/128a84846eda9913624a to your computer and use it in GitHub Desktop.
Save Proteas/128a84846eda9913624a to your computer and use it in GitHub Desktop.
Race Condition
#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;
}
@dtron057
Copy link

fineshed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment