/*
 * DF-1919 fix-validation harness — models the EXACT predicate added by
 * fix.diff (mrsas_ioctl.c:266-267) plus the bus_size_t widening and the
 * copyin-uses-ioctl_data_size change.  Shows the truncated iov_len
 * vectors that previously overflowed are now rejected up-front.
 *
 * Build:  cc -O2 -o fixcheck fixcheck.c
 * Run:    ./fixcheck
 */
#include <stdio.h>
#include <stdint.h>

#define MRSAS_IOCTL_MAX_DATA_SIZE (1024 * 1024)   /* 1 MiB per SGE */

/* Verbatim predicate from fix.diff DF-1919 (mrsas_ioctl.c:266-267).
 * `iov_len` modeled as uint64_t (size_t on amd64). */
static int fixed_reject(uint64_t iov_len)
{
    if (iov_len == 0 || iov_len > MRSAS_IOCTL_MAX_DATA_SIZE)
        return 1;
    return 0;
}

int main(void)
{
    struct { const char *label; uint64_t iov_len; } v[] = {
        { "benign",            0x40ull },
        { "truncated-small",   0x100000008ull },   /* canonical: alloc 8, copyin 4GiB+8 */
        { "truncated-page",    0x100001000ull },
        { "truncated-zero-lo", 0x100000000ull },
        { "truncated-neg",     0x1FFFFFFFFull },
        { "truncated-large",   0x200000800ull },
    };
    unsigned rejected = 0, total = sizeof(v)/sizeof(v[0]);
    printf("DF-1919 fix check (mrsas_ioctl.c:266-267 patched predicate + bus_size_t):\n");
    for (unsigned i = 0; i < total; i++) {
        int r = fixed_reject(v[i].iov_len);
        printf("  %-22s iov_len=0x%016llx -> %s\n",
               v[i].label, (unsigned long long)v[i].iov_len,
               r ? "REJECTED (EINVAL) -- would have overflowed"
                 : "accepted (in-bounds)");
        if (r) rejected++;
    }
    printf("  %u/%u vectors rejected by the fix predicate.\n", rejected, total);
    return 0;
}
