<commit_before>#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <fcntl.h>
#include <sys/ptrace.h>
#include <sys/reg.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/user.h>
#include <sys/wait.h>
#include <unistd.h>

#include "config.h"
#include "database.h"


/* *************************************
 * Tracee-manipulating functions
 */

size_t tracee_strlen(pid_t pid, size_t ptr)
{
    size_t j = ptr % WORD_SIZE;
    size_t i = ptr - j;
    size_t size = 0;
    int done = 0;
    for(; !done; i += WORD_SIZE)
    {
        unsigned int data = ptrace(PTRACE_PEEKDATA, pid, i, NULL);
        for(; !done && j < WORD_SIZE; ++j)
        {
            unsigned char byte = data >> (8 * j);
            if(byte == 0)
                done = 1;
            else
                ++size;
        }
        j = 0;
    }
    return size;
}

void tracee_read(pid_t pid, char *dst, size_t ptr, size_t size)
{
    size_t j = ptr % WORD_SIZE;
    size_t i = ptr - j;
    size_t end = ptr + size;
    for(; i < end; i += WORD_SIZE)
    {
        unsigned int data = ptrace(PTRACE_PEEKDATA, pid, i, NULL);
        for(; j < WORD_SIZE && i + j < end; ++j)
            *dst++ = data >> (8 * j);
        j = 0;
    }
}


/* *************************************
 * Tracer
 */

#define PROCESS_FREE        0
#define PROCESS_ALLOCATED   1
#define PROCESS_ATTACHED    2

struct Syscall {
    int n;
    char *path;
    int mode;
};

struct Process {
    unsigned int identifier;
    pid_t pid;
    int status;
    int in_syscall;
    struct Syscall current_syscall;
};

struct Process **processes;
size_t processes_size;
unsigned int next_identifier = 0;

struct Process *trace_find_process(pid_t pid)
{
    size_t i;
    for(i = 0; i < processes_size; ++i)
    {
        if(processes[i]->status != PROCESS_FREE && processes[i]->pid == pid)
            return processes[i];
    }
    return NULL;
}

struct Process *trace_get_empty_process(void)
{
    size_t i;
    for(i = 0; i < processes_size; ++i)
    {
        if(processes[i]->status == PROCESS_FREE)
            return processes[i];
    }

    /* Allocate more! */
    {
        struct Process *pool, *ret;
        processes_size *= 2;
        pool = malloc((processes_size - i) * sizeof(*pool));
        processes = realloc(processes, processes_size);
        ret = processes[i];
        for(; i < processes_size; ++i)
        {
            processes[i] = pool++;
            processes[i]->status = PROCESS_FREE;
            processes[i]->in_syscall = 0;
            processes[i]->current_syscall.n = -1;
        }
        return ret;
    }
}

static unsigned int flags2mode(int flags)
{
    unsigned int mode = 0;
    if(!O_RDONLY)
    {
        if(flags & O_WRONLY)
            mode |= FILE_WRITE;
        else if(flags & O_RDWR)
            mode |= FILE_READ | FILE_WRITE;
        else
            mode |= FILE_READ;
    }
    else if(!O_WRONLY)
    {
        if(flags & O_RDONLY)
            mode |= FILE_READ;
        else if(flags & O_RDWR)
            mode |= FILE_READ | FILE_WRITE;
        else
            mode |= FILE_WRITE;
    }
    else
    {
        if( (flags & (O_RDONLY | O_WRONLY)) == (O_RDONLY | O_WRONLY) )
            fprintf(stderr, "Error: encountered bogus open() flags "
                    "O_RDONLY|O_WRONLY\n");
            /* Carry on anyway */
        if(flags & O_RDONLY)
            mode |= FILE_READ;
        if(flags & O_WRONLY)
            mode |= FILE_WRITE;
        if(flags & O_RDWR)
            mode |= FILE_READ | FILE_WRITE;
    }
    return mode;
}

void trace_handle_syscall(struct Process *process, int syscall, size_t *params)
{
    pid_t pid = process->pid;
#ifdef DEBUG
    if(syscall == SYS_open || syscall == SYS_execve || syscall == SYS_fork
     || syscall == SYS_vfork || syscall == SYS_clone)
    {
        const char *callname = (syscall == SYS_open)?"open":
                               (SYS_execve)?"execve":
                               (SYS_fork)?"fork":
                               (SYS_vfork)?"vfork":
                               "clone";
        fprintf(stderr, "syscall=%u %s, in_syscall=%u\n",
                syscall, callname, process->in_syscall);
    }
#endif
    if(!process->in_syscall
     && (syscall == SYS_open || syscall == SYS_execve) )
    {
        size_t pathname_addr = params[0];
        size_t pathname_size = tracee_strlen(pid, pathname_addr);
        char *pathname = malloc(pathname_size + 1);
        tracee_read(pid, pathname, pathname_addr, pathname_size);
        pathname[pathname_size] = '\0';
        process->current_syscall.n = syscall;
        process->current_syscall.path = pathname;
#ifdef DEBUG
        fprintf(stderr, "    %s\n", pathname);
#endif
        if(syscall == SYS_execve)
            process->current_syscall.mode = FILE_EXEC;
        else
            process->current_syscall.mode = flags2mode((int)params[1]);
    }
    else if(process->in_syscall
          && (syscall == SYS_open || syscall == SYS_execve) )
    {
        int ret = params[0];
        if(ret >= 0)
        {
#ifdef DEBUG
            fprintf(stderr, "File %s\n", process->current_syscall.path);
#endif
            db_add_file_open(process->identifier,
                             process->current_syscall.path,
                             process->current_syscall.mode);
        }
        else<commit_msg>Fixes major typo<commit_after>#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <fcntl.h>
#include <sys/ptrace.h>
#include <sys/reg.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/user.h>
#include <sys/wait.h>
#include <unistd.h>

#include "config.h"
#include "database.h"


/* *************************************
 * Tracee-manipulating functions
 */

size_t tracee_strlen(pid_t pid, size_t ptr)
{
    size_t j = ptr % WORD_SIZE;
    size_t i = ptr - j;
    size_t size = 0;
    int done = 0;
    for(; !done; i += WORD_SIZE)
    {
        unsigned int data = ptrace(PTRACE_PEEKDATA, pid, i, NULL);
        for(; !done && j < WORD_SIZE; ++j)
        {
            unsigned char byte = data >> (8 * j);
            if(byte == 0)
                done = 1;
            else
                ++size;
        }
        j = 0;
    }
    return size;
}

void tracee_read(pid_t pid, char *dst, size_t ptr, size_t size)
{
    size_t j = ptr % WORD_SIZE;
    size_t i = ptr - j;
    size_t end = ptr + size;
    for(; i < end; i += WORD_SIZE)
    {
        unsigned int data = ptrace(PTRACE_PEEKDATA, pid, i, NULL);
        for(; j < WORD_SIZE && i + j < end; ++j)
            *dst++ = data >> (8 * j);
        j = 0;
    }
}


/* *************************************
 * Tracer
 */

#define PROCESS_FREE        0
#define PROCESS_ALLOCATED   1
#define PROCESS_ATTACHED    2

struct Syscall {
    int n;
    char *path;
    int mode;
};

struct Process {
    unsigned int identifier;
    pid_t pid;
    int status;
    int in_syscall;
    struct Syscall current_syscall;
};

struct Process **processes;
size_t processes_size;
unsigned int next_identifier = 0;

struct Process *trace_find_process(pid_t pid)
{
    size_t i;
    for(i = 0; i < processes_size; ++i)
    {
        if(processes[i]->status != PROCESS_FREE && processes[i]->pid == pid)
            return processes[i];
    }
    return NULL;
}

struct Process *trace_get_empty_process(void)
{
    size_t i;
    for(i = 0; i < processes_size; ++i)
    {
        if(processes[i]->status == PROCESS_FREE)
            return processes[i];
    }

    /* Allocate more! */
    {
        struct Process *pool, *ret;
        processes_size *= 2;
        pool = malloc((processes_size - i) * sizeof(*pool));
        processes = realloc(processes, processes_size);
        ret = processes[i];
        for(; i < processes_size; ++i)
        {
            processes[i] = pool++;
            processes[i]->status = PROCESS_FREE;
            processes[i]->in_syscall = 0;
            processes[i]->current_syscall.n = -1;
        }
        return ret;
    }
}

static unsigned int flags2mode(int flags)
{
    unsigned int mode = 0;
    if(!O_RDONLY)
    {
        if(flags & O_WRONLY)
            mode |= FILE_WRITE;
        else if(flags & O_RDWR)
            mode |= FILE_READ | FILE_WRITE;
        else
            mode |= FILE_READ;
    }
    else if(!O_WRONLY)
    {
        if(flags & O_RDONLY)
            mode |= FILE_READ;
        else if(flags & O_RDWR)
            mode |= FILE_READ | FILE_WRITE;
        else
            mode |= FILE_WRITE;
    }
    else
    {
        if( (flags & (O_RDONLY | O_WRONLY)) == (O_RDONLY | O_WRONLY) )
            fprintf(stderr, "Error: encountered bogus open() flags "
                    "O_RDONLY|O_WRONLY\n");
            /* Carry on anyway */
        if(flags & O_RDONLY)
            mode |= FILE_READ;
        if(flags & O_WRONLY)
            mode |= FILE_WRITE;
        if(flags & O_RDWR)
            mode |= FILE_READ | FILE_WRITE;
    }
    return mode;
}

void trace_handle_syscall(struct Process *process, int syscall, size_t *params)
{
    pid_t pid = process->pid;
#ifdef DEBUG
    if(syscall == SYS_open || syscall == SYS_execve || syscall == SYS_fork
     || syscall == SYS_vfork || syscall == SYS_clone)
    {
        const char *callname = (syscall == SYS_open)?"open":
                               (SYS_execve)?"execve":
                               (SYS_fork)?"fork":
                               (SYS_vfork)?"vfork":
                               "clone";
        fprintf(stderr, "syscall=%u %s, in_syscall=%u\n",
                syscall, callname, process->in_syscall);
    }
#endif
    if(!process->in_syscall
     && (syscall == SYS_open || syscall == SYS_execve) )
    {
        size_t pathname_addr = params[0];
        size_t pathname_size = tracee_strlen(pid, pathname_addr);
        char *pathname = malloc(pathname_size + 1);
        tracee_read(pid, pathname, pathname_addr, pathname_size);
        pathname[pathname_size] = '\0';
        process->current_syscall.n = syscall;
        process->current_syscall.path = pathname;
#ifdef DEBUG
        fprintf(stderr, "    %s\n", pathname);
#endif
        if(syscall == SYS_execve)
            process->current_syscall.mode = FILE_EXEC;
        else
            process->current_syscall.mode = flags2mode((int)params[1]);
    }
    else if(process->in_syscall
          && (syscall == SYS_open || syscall == SYS_execve) )
    {
        int ret = params[-1];
        if(ret >= 0)
        {
#ifdef DEBUG
            fprintf(stderr, "File %s\n", process->current_syscall.path);
#endif
            db_add_file_open(process->identifier,
                             process->current_syscall.path,
                             process->current_syscall.mode);
        }
        else
{'fraction_non_alphanumeric': 0.13899150350942002, 'fraction_numerical': 0.004802364240857037, 'mean_word_length': 1.958743169398907, 'pattern_counts': {'":': 8, '<': 43, '<?xml version=': 0, '>': 75, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1282089', 'n_tokens_mistral': 3745, 'n_tokens_neox': 3568, 'n_words': 811}