โฌข DragonFlyBSD Kernel Audit
DF-3970 / trigger.c
โ† back to finding โ†“ download raw
/*
 * DF-3970 trigger sketch โ€” rt2560_set_chan unbounded RT2560_RF5222 table walk
 * ===========================================================================
 * rt2560.c:2209-2215:
 *   case RT2560_RF_5222:
 *           for (i = 0; rt2560_rf5222[i].chan != chan; i++);
 *
 *           rt2560_rf_write(sc, RAL_RF1, rt2560_rf5222[i].r1);
 *           ...
 *
 * The 41-entry table (rt2560reg.h:449-489) has NO terminator and the loop
 * has NO bound. The default channel lists built by ieee80211_init_channels
 * (ieee80211_regdomain.c:101-108: 2GHz 1-14, 5GHz 36-64/100-140/149-161)
 * happen to be fully covered, so out-of-the-box systems never miss. But
 * SIOCS80211/IEEE80211_IOC_REGDOMAIN (ieee80211_ioctl.c:2126-2162 ->
 * ieee80211_regdomain.c:342+ -> null_setregdomain accepts ANYTHING,
 * regdomain.c:59-65) lets an admin install an arbitrary channel table
 * (only freq/flags/maxregpower are validated, NOT the ieee number against
 * driver RF tables), and memcpy it into ic->ic_channels. Selecting a
 * channel whose ic_ieee is not one of the 41 table entries (e.g. 165, 34,
 * 184-196) makes the scan walk off the end of .rodata until some byte
 * happens to equal `chan` โ€” OOB read across kernel rodata + garbage r1/r2/
 * r4 programmed into the RF registers.
 *
 * On-hardware trigger (needs an RT2560/RT5222 dual-band NIC; root):
 *   # ifconfig wlan0 down                          # vaps must be down
 *   # regdomain-set <cc> with a channel table containing ieee=165 / 5825MHz
 *   #   (or use a small tool issuing SIOCS80211 IEEE80211_IOC_REGDOMAIN
 *   #    with reg.chaninfo including {ic_ieee=165, ic_freq=5825,
 *   #    ic_flags=IEEE80211_CHAN_A, ic_maxregpower=30})
 *   # ifconfig wlan0 channel 165                   # -> walk off table end
 *
 * Kernel .data/.rodata is fully mapped so the walk almost surely terminates
 * on a coincidental byte match within a few KB; impact is an OOB read
 * (info not returned to user) plus misprogrammed RF โ€” Low.
 */
#include <stdio.h>
int main(void) {
    printf("hardware-gated + root-config: see header comment for the recipe\n");
    return 0;
}