/*
 * ASAN demonstration harness: sys/libkern/bcmp.c (verbatim, as df_bcmp)
 * reads past the end of heap buffers.
 *
 * Each case mallocs EXACTLY off+N bytes so the ASAN redzone hugs the region
 * the caller hands to bcmp.  Expected findings (from source analysis):
 *   - aligned path tail  (bcmp.c:128-129): 8 - (N%8) bytes past end
 *   - shifted-path tail  (bcmp.c:110-111): up to 7 bytes past end
 *   - shifted-path loop  (bcmp.c:89-91):   vb load up to 7 bytes past end
 * Compile with -fsanitize=address.  Any ASAN report = OOB read proven.
 * Exit code 0 with reports counted via __asan_on_error / death callback.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

int df_bcmp(const void *, const void *, size_t);

static int asan_hits = 0;
void __asan_on_error(void) { asan_hits++; }

int main(int argc, char **argv)
{
    int only = (argc > 1) ? atoi(argv[1]) : 0;   /* run a single case id */
    int cases = 0;
    long total_reads_flagged = 0;

    for (int off1 = 0; off1 < 8; off1++) {
        for (int off2 = 0; off2 < 8; off2++) {
            for (size_t n = 1; n <= 40; n++) {
                cases++;
                if (only && cases != only) continue;
                size_t sz1 = (size_t)off1 + n;
                size_t sz2 = (size_t)off2 + n;
                unsigned char *b1 = malloc(sz1);
                unsigned char *b2 = malloc(sz2);
                if (!b1 || !b2) { perror("malloc"); return 2; }
                memset(b1, 0x5a, sz1);
                memset(b2, 0x5a, sz2);   /* equal content: runs to the tail */
                volatile int r = df_bcmp(b1 + off1, b2 + off2, n);
                (void)r;
                free(b1); free(b2);
            }
        }
    }
    total_reads_flagged = asan_hits;
    printf("ran %d (%s) case configurations; __asan_on_error hits: %ld\n",
           cases, only ? "single" : "all", total_reads_flagged);
    printf("RESULT: %s — heap OOB READ %s by df_bcmp\n",
           asan_hits ? "OOB-CONFIRMED" : "no-report",
           asan_hits ? "demonstrated" : "not seen");
    return asan_hits ? 0 : 1;
}
