0vercl0k / wtf

wtf is a distributed, code-coverage guided, customizable, cross-platform snapshot-based fuzzer designed for attacking user and / or kernel-mode targets running on Microsoft Windows and Linux user-mode (experimental!).
MIT License
1.46k stars 130 forks source link

wtf on multi-threaded program #185

Closed J-jaeyoung closed 1 year ago

J-jaeyoung commented 1 year ago

Hello, I have tried to discover race condition bugs with wtf. After some experiments with the following sample target, I've concluded bochscpu doesn't emulate timer interrupt, which means that thread-switching doesn't occur at all.

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <stdio.h>
#include <Windows.h>
#include <inttypes.h>
#define MAX_ITER 1000000

void nop() {
    return;
}

void crash() {
    printf("CRASH!\n");
    *(int*)0xdeafbeef = 1;
}

void (*mem[2])() = {nop, crash};
uint64_t shared = 0;

DWORD WINAPI Racer(LPVOID lpParam) {
    int threadId = *(int*)lpParam;
    for (int i = 0; i < MAX_ITER; i++) {
        shared = 1 - shared; // flip
    }
    return 0;
}

void call(uint64_t idx) {
    (mem[idx])();
}

int main() {
    HANDLE threads;
    int threadId;
    scanf("%*c");

    threads = CreateThread(NULL, 0, Racer, &threadId, 0, NULL);
    if (!threads) {
        return -1;
    }

// <-- snapshot point
    for (int i = 0; i < MAX_ITER; i++) {
        shared = 0;
        if (shared == 0) {
            call(shared); // <-- double fetch bug (compiled without any optimizations)
        }
    }

    WaitForMultipleObjects(1, &threads, TRUE, INFINITE);
    CloseHandle(threads);

    return 0;
}

If I understand correctly, wtf cannot detect multithread-related race bugs, is it right? Could kvm or whv be potential solutions for detecting these bugs, or is there any possible workarounds?

Thanks.

0vercl0k commented 1 year ago

You are correct, the runtime environment has no interruption happening. This is done so that you don't burn time fuzzing something that isn't your target (another random process for example).

Technically what you want to do is probably possible but hard to make generic. wtf would need to know the threads of your target and artificially context switch into them. You could imagine forcing a context switch after a maximum of instruction and when the threads yield but it isn't implemented and I haven't played with this idea either. It's always been on the back of my mind though, so if you end up trying to make something work, let me know!

Cheers

J-jaeyoung commented 1 year ago

Oh, now I clearly understand what's going on. I should experiment more with wtf and try implementing it on weekends.

Thank you for this wonderful project.

0vercl0k commented 1 year ago

Thank you for trying it out 🙏🏽!