/* DF-1560: pp_dpm_set_pp_table sysfs heap overflow harness.
 * kmemdup(soft_pp_table, soft_pp_table_size=2000) then memcpy(buf, size=4096)
 * overflows ~2096 bytes into adjacent slab.
 */
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>

static int fixed = 0;

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

    size_t soft_pp_table_size = 2000;  /* from VBIOS */
    char *hardcode_pp_table = malloc(soft_pp_table_size);
    if (!hardcode_pp_table) return 1;

    char sysfs_buf[4096];
    memset(sysfs_buf, 'A', sizeof(sysfs_buf));
    size_t size = sizeof(sysfs_buf);

    /* Pre-fix: memcpy(hardcode_pp_table, buf, size); */
    /* Post-fix: clamp size first */
    if (fixed) {
        if (size > soft_pp_table_size) size = soft_pp_table_size;
    }
    if (size > soft_pp_table_size) {
        printf("OVERFLOW: would write %zu bytes into %zu-byte alloc (%zu bytes OOB)\n",
               size, soft_pp_table_size, size - soft_pp_table_size);
        printf("RESULT: BUGGY\n");
    } else {
        memcpy(hardcode_pp_table, sysfs_buf, size);
        printf("RESULT: PATCHED - size clamped to %zu (alloc %zu)\n", size, soft_pp_table_size);
    }
    free(hardcode_pp_table);
    return 0;
}
