DF-5032 / oob_demo.c
/* * DF-5032: bounds demonstration for ar5212GetRfField() call sites in * sys/dev/netif/ath/ath_hal/ar5212/ar5212_rfgain.c. * * Replicates the exact array-walk arithmetic of ar5212GetRfField() * (ar5212_rfgain.c:102-117) for every call site in the file and prints * which rfBuf[] (== RF bank 7) words are touched, against the actual * N(ar5212Bank7_*) row counts from sys/.../ar5212/ar5212.ini: * * ar5212Bank7_5111 : 8 rows ar5212Bank7_2316 : 3 rows * ar5212Bank7_5112 : 13 rows ar5212Bank7_5413 : 3 rows * ar5212Bank7_2413 : 3 rows ar5212Bank7_2317 : 3 rows * ar5212Bank7_2425 : 3 rows */ #include <stdio.h> struct site { const char *name; unsigned numBits, firstBit, col; }; static const struct site sites[] = { /* ar5212_rfgain.c:129 - 5112 path: mixOvr */ { "InvalidGainReadback/5112 GetRfField(bank7, 1, 36, 0)", 1, 36, 0 }, /* ar5212_rfgain.c:140 - non-5112 path: gStep <-- the bug */ { "InvalidGainReadback/else GetRfField(bank7, 6, 37, 0)", 6, 37, 0 }, /* ar5212_rfgain.c:251 - 5112 rev2: mixOvr */ { "GetGainFCorrection GetRfField(bank7, 1, 36, 0)", 1, 36, 0 }, /* ar5212_rfgain.c:255 - 5112 rev2: gainStep */ { "GetGainFCorrection GetRfField(bank7, 4, 32, 0)", 4, 32, 0 }, }; struct bank { const char *radio; const char *macro; int rows; }; static const struct bank banks[] = { { "ar5111 (else path)", "N(ar5212Bank7_5111)", 8 }, { "ar5112 (if path)", "N(ar5212Bank7_5112)", 13 }, { "ar2413 (else path)", "N(ar5212Bank7_2413)", 3 }, { "ar2316 (else path)", "N(ar5212Bank7_2316)", 3 }, { "ar5413 (else path)", "N(ar5212Bank7_5413)", 3 }, { "ar2317 (else path)", "N(ar5212Bank7_2317)", 3 }, { "ar2425/2417 (else)", "N(ar5212Bank7_2425)", 3 }, }; int main(void) { unsigned maxword = 0; size_t i, b; int bad = 0; for (i = 0; i < sizeof(sites) / sizeof(sites[0]); i++) { const struct site *s = &sites[i]; unsigned arrayEntry = (s->firstBit - 1) / 8; unsigned bitPosition = (s->firstBit - 1) % 8; int bitsLeft = s->numBits; unsigned hi = 0; printf("%s\n words touched:", s->name); while (bitsLeft > 0) { printf(" [%u]", arrayEntry); if (arrayEntry > hi) hi = arrayEntry; bitsLeft -= (8 - bitPosition); bitPosition = 0; arrayEntry++; } printf(" (max index %u)\n", hi); } printf("\n--- max index per call site vs bank7 rows ---\n"); /* the non-5112 gStep read is the only site that can exceed 3 rows */ { unsigned ae = (37 - 1) / 8, bp = (37 - 1) % 8; int bl = 6; maxword = 0; while (bl > 0) { if (ae > maxword) maxword = ae; bl -= (8 - bp); bp = 0; ae++; } } for (b = 0; b < sizeof(banks) / sizeof(banks[0]); b++) { int oob = (int)maxword >= banks[b].rows; printf("%-24s %-22s = %2d rows -> index %u %s\n", banks[b].radio, banks[b].macro, banks[b].rows, maxword, oob ? "*** OUT OF BOUNDS (reads 2 words past) ***" : "ok"); if (oob) bad = 1; } printf("\nverdict: ar5212InvalidGainReadback() reads rfBuf[4] and " "rfBuf[5]\nfor every non-5112/5111 radio; their bank 7 has only 3 " "words.\n"); return bad; } |