// binder_fuzzer.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/epoll.h>
#include <linux/android/binder.h>

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <input_file>\n", argv[0]);
        return 1;
    }

    // Read fuzzer input
    FILE *f = fopen(argv[1], "rb");
    if (!f) return 1;
    
    fseek(f, 0, SEEK_END);
    long fsize = ftell(f);
    fseek(f, 0, SEEK_SET);
    
    unsigned char *buffer = malloc(fsize + 1);
    fread(buffer, fsize, 1, f);
    fclose(f);
    
    // Open binder device
    int fd_binder = open("/dev/binder", O_RDWR);
    if (fd_binder < 0) return 1;
    
    // Create an epoll instance
    int fd_epoll = epoll_create(1);
    if (fd_epoll < 0) return 1;
    
    // Add binder to epoll
    struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = fd_binder;
    epoll_ctl(fd_epoll, EPOLL_CTL_ADD, fd_binder, &ev);
    
    // Use input data as parameters for ioctl calls
    struct binder_write_read bwr = {0};
    if (fsize >= sizeof(bwr)) {
        memcpy(&bwr, buffer, sizeof(bwr));
    }
    
    // Try various binder operations
    ioctl(fd_binder, BINDER_VERSION, &bwr);
    ioctl(fd_binder, BINDER_WRITE_READ, &bwr);
    ioctl(fd_binder, BINDER_THREAD_EXIT, 0);
    
    // Try to trigger the bug
    close(fd_binder);
    epoll_ctl(fd_epoll, EPOLL_CTL_DEL, fd_binder, &ev);
    
    close(fd_epoll);
    free(buffer);
    return 0;
}