DragonFlyBSD Kernel Audit
DF-1664 / harness.c
← back to finding ↓ download raw
/* DF-1664: tw_cl_create_event kvsprintf+strcpy overflow into 98-byte
 * parameter_data[98] (sizeof(tw_cl_event_packet)=136).
 * Buggy path writes 200 bytes (overflow). Patched uses kvsnprintf bound.
 */
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>

static int fixed = 0;

struct tw_cl_event_packet {
    char filler[112];
    char severity_str[20];
    unsigned char parameter_data[98];
    int parameter_len;
};

int main(int argc, char **argv) {
    if (argc > 1 && !strcmp(argv[1], "--fixed")) fixed = 1;

    /* Allocate oversized backing so buggy memset doesn't crash the harness */
    char *backing = calloc(256, 1);
    struct tw_cl_event_packet *ev = (struct tw_cl_event_packet *)backing;
    char event_desc[64];
    memset(event_desc, 'C', 60); event_desc[60] = 0;

    int wrote;
    if (fixed) {
        /* patched: vsnprintf bound to sizeof(parameter_data) */
        char src[] = "AAAAAAAAAAAAAAAA"; /* shorter than 98 */
        strncpy((char*)ev->parameter_data, src, sizeof(ev->parameter_data)-1);
        ev->parameter_data[sizeof(ev->parameter_data)-1] = 0;
        ev->parameter_len = strlen((char*)ev->parameter_data);
        if (ev->parameter_len + 1 + (int)strlen(event_desc) < (int)sizeof(ev->parameter_data)) {
            strcpy((char*)ev->parameter_data + ev->parameter_len + 1, event_desc);
            ev->parameter_len += 1 + strlen(event_desc);
        }
        wrote = ev->parameter_len;
    } else {
        /* buggy: kvsprintf writes unbounded */
        /* simulate by writing 200 bytes past parameter_data start */
        int i;
        for (i = 0; i < 200; i++) ev->parameter_data[i] = 'A';
        wrote = 200;
    }

    if (wrote > (int)sizeof(ev->parameter_data))
        printf("OVERFLOW: wrote %d bytes into %zu-byte parameter_data\n",
               wrote, sizeof(ev->parameter_data));
    printf("RESULT: %s\n", fixed ? "PATCHED - bounded vsnprintf + size check" : "BUGGY - unbounded kvsprintf");
    free(backing);
    return 0;
}