DragonFlyBSD Kernel Audit
DF-1341 / trigger.c
← back to finding ↓ download raw
/* DF-1341 r600_texture_size: nlevels = llevel - blevel + 1 underflow */
#include <stdio.h>
#include <stdint.h>

static uint32_t nlevels_vuln(unsigned blevel, unsigned llevel){
    unsigned nlevels = llevel - blevel + 1;     /* wraps to ~4B if blevel > llevel */
    return nlevels;
}
static int nlevels_fixed(unsigned blevel, unsigned llevel){
    if (blevel > llevel) return -1;
    return (int)(llevel - blevel + 1);
}

int main(void){
    /* MSAA path forces llevel=0 *after* blevel is parsed from word4 */
    unsigned blevel = 5, llevel = 0;
    printf("== BEFORE-FIX (vulnerable) ==\n");
    uint32_t n = nlevels_vuln(blevel, llevel);
    printf("BUG: nlevels = llevel(%u) - blevel(%u) + 1 = %u (unsigned underflow), loop iterates ~4B times\n",
           llevel, blevel, n);
    printf("== AFTER-FIX ==\n");
    int rc = nlevels_fixed(blevel, llevel);
    printf("FIX: blevel(%u) > llevel(%u) -> return -EINVAL (rc=%d)\n", blevel, llevel, rc);
    return 0;
}