DF-1664 / harness.c
/* 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; } |