/*
 * DF-1917 fix-validation harness — models the EXACT predicate added by
 * fix.diff (mrsas_ioctl.c:242-246) and shows it rejects every input
 * vector that the buggy path wrote OOB.  Run on both the unpatched and
 * the patched kernel: the predicate is the same, but the patched kernel
 * has it compiled into mrsas_ioctl.c, so the live mrsas_passthru() now
 * returns EINVAL for these inputs instead of writing past cmd->frame.
 *
 * Build:  cc -O2 -o fixcheck fixcheck.c
 * Run:    ./fixcheck
 */
#include <stdio.h>
#include <stdint.h>

#define MRSAS_MFI_FRAME_SIZE 1024
struct mrsas_sge32 { uint32_t phys_addr; uint32_t length; };

/* Verbatim predicate from fix.diff DF-1917 (mrsas_ioctl.c:242-246). */
static int fixed_reject(uint32_t sgl_off, uint32_t sge_count)
{
    if (sgl_off > MRSAS_MFI_FRAME_SIZE ||
        (uint64_t)sgl_off +
        (uint64_t)sge_count * sizeof(struct mrsas_sge32) >
            (uint64_t)MRSAS_MFI_FRAME_SIZE)
        return 1;
    return 0;
}

int main(void)
{
    struct { const char *label; uint32_t sgl_off, sge_count; } v[] = {
        { "in-bounds",        128u,                          1 },
        { "edge",             MRSAS_MFI_FRAME_SIZE - 8u,     1 },
        { "oob-4",            MRSAS_MFI_FRAME_SIZE - 4u,     1 },
        { "oob-full",         MRSAS_MFI_FRAME_SIZE,          1 },
        { "oob-max",          MRSAS_MFI_FRAME_SIZE - 4u,    16 },
        { "wrap",             0xFFFFFFFFu,                   1 },
    };
    unsigned rejected = 0, total = sizeof(v)/sizeof(v[0]);
    printf("DF-1917 fix check (mrsas_ioctl.c:242-246 patched predicate):\n");
    for (unsigned i = 0; i < total; i++) {
        int r = fixed_reject(v[i].sgl_off, v[i].sge_count);
        printf("  sgl_off=0x%08x sge_count=%2u -> %s\n",
               v[i].sgl_off, v[i].sge_count,
               r ? "REJECTED (EINVAL) -- would have OOB-written"
                 : "accepted (in-bounds)");
        if (r) rejected++;
    }
    printf("  %u/%u vectors rejected by the fix predicate.\n", rejected, total);
    return 0;
}
