When the Kernel Turns Against You - Linux ≠ Freedom of choice?

Restoring Regional Wi‑Fi Freedom DFS‑ETSI
Linux is often celebrated as the epitome of user freedom and control. Yet hidden deep in the kernel is a tension between regulatory compliance and user autonomy, vividly exposed when Wi-Fi cards refuse to operate on legal frequencies. This article explains why Linux sometimes overrides explicit user settings for regional wireless rules, how cryptographic signatures and defaults enforce strict limitations, and what steps can restore proper regional operation.
Read first: Altering regulatory behaviour can place equipment outside certification scope. Always align final transmitted power, channel width, and indoor/outdoor use with the rules of the jurisdiction in which the radio operates. Numbers shown here reflect data observed during testing and user‑supplied regulatory guidance; confirm against current regulator publications before deployment.
Why This Matters Everywhere (GB Used as Worked Example)
Getting stuck in the conservative world regulatory domain (country 00: DFS-UNSET
) robs hardware of lawfully usable spectrum: reduced transmit power, disabled AP (NO‑IR) on many 5 GHz / 6 GHz channels, DFS untreated, and country‑specific indoor/outdoor splits ignored. The mechanism that forces the fallback is global in Linux: if cfg80211 cannot verify (or is told to require verification of) a regulatory database, it drops to the safe world table. Thus the same failure that hid legal GB allocations will hide FCC, ETSI‑region, JP, and other national rules. Fix it once; benefit everywhere.
Our path: discover kernel rebuilds were silently re‑enabling signature enforcement; patch the Kconfig defaults; enforce them through the build pipeline; deploy a current wireless‑regdb; confirm region GB
now shows DFS-ETSI
and that AP operation on permitted channels succeeds.
Symptom Timeline
Observed:
iw reg get
showedcountry 00: DFS-UNSET
despite attempts to set GB.- hostapd logged
Frequency 5180 not allowed for AP mode
,Primary frequency not allowed
, orIEEE 802.11 Hardware does not support configured channel
on otherwise capable radios. .config
was manually edited (CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=n
), yet aftermake -j32
the line reappeared asCONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y
— caught by diffing a pre‑build copy of.config
against the post‑build one.- Similar behaviour for
CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS
.
Result: user‑supplied / updated regulatory.db
ignored; kernel fell back to world domain; GB legal channels unavailable.
Regulatory Stack Primer
Linux wireless regulatory enforcement involves three moving parts:
- cfg80211 (kernel subsystem): holds the in‑kernel regulatory rules actually enforced on channels. It may load data from a regulatory database and/or from the wireless driver/firmware.
- wireless‑regdb (userspace data project): source of canonical regional channel/power/DFS rules; compiled to
regulatory.db
consumed by cfg80211. - Signature policy (Kconfig): determines whether cfg80211 accepts an unsigned regulatory database. If signatures are required and validation fails, cfg80211 will not trust the file and instead use a built‑in, extremely conservative world domain.
Because (3) gates (2), a misconfigured build can negate all downstream attempts to set a correct country code.
The Two Gatekeeper Kconfig Options
Symbol | Default (many trees) | Effect | Failure Mode When Left On |
---|---|---|---|
CFG80211_REQUIRE_SIGNED_REGDB |
y |
Only accept a PKCS#7‑signed regulatory.db that validates against a trusted cert in the kernel keyring. |
Unsigned / locally edited DB rejected → fall back to 00 global domain; region stuck at DFS-UNSET . |
CFG80211_USE_KERNEL_REGDB_KEYS |
y |
Compile in key(s) shipped with kernel sources (historically Seth Forshee’s regdb maintainer key) so shipped db signatures validate. | Local DB signed with different key fails; or if .p7s missing, verification fails → fallback. |
Snippet from net/wireless/Kconfig
config CFG80211_REQUIRE_SIGNED_REGDB
bool "require regdb signature" if CFG80211_CERTIFICATION_ONUS
default y
select SYSTEM_DATA_VERIFICATION
help
Require that in addition to the "regulatory.db" file a
"regulatory.db.p7s" can be loaded with a valid PKCS#7
signature for the regulatory.db file made by one of the
keys in the certs/ directory.
config CFG80211_USE_KERNEL_REGDB_KEYS
bool "allow regdb keys shipped with the kernel" if CFG80211_CERTIFICATION_ONUS
default y
depends on CFG80211_REQUIRE_SIGNED_REGDB
help
Allow the regulatory database to be signed by one of the keys for
which certificates are part of the kernel sources
(in net/wireless/certs/).
Leaving both at y
is the safe vendor default; turning them off hands responsibility back to the system builder.
Minimal Patch: Flip y
→ n
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -91,7 +91,7 @@
config CFG80211_REQUIRE_SIGNED_REGDB
bool "require regdb signature" if CFG80211_CERTIFICATION_ONUS
- default y
+ default n
select SYSTEM_DATA_VERIFICATION
@@ -101,7 +101,7 @@
config CFG80211_USE_KERNEL_REGDB_KEYS
bool "allow regdb keys shipped with the kernel" if CFG80211_CERTIFICATION_ONUS
- default y
+ default n
depends on CFG80211_REQUIRE_SIGNED_REGDB
Captured test diff (Linux 6.12.30 tree):
diff linux-6.12.30/net/wireless/Kconfig linux-6.12.30-orig/net/wireless/Kconfig
94c94
< default n
---
> default y
104c104
< default n
---
> default y
Build Discipline: Keeping Options from Reverting
Many distributions layer config fragments; olddefconfig
and automated scripts can silently re‑enable defaults. Guard the process:
# Save pre‑build copy
cp .config .config.pre
# Build
make -j$(nproc)
# Compare
cmp -s .config .config.pre || diff -u .config.pre .config | less
If the two cfg80211 lines flipped back to y
, re‑apply overrides after fragment merges and before the final olddefconfig
. For scripted builds use scripts/kconfig/merge_config.sh
with a local fragment containing:
# cfg80211 local overrides
# CONFIG_CFG80211_REQUIRE_SIGNED_REGDB is not set
# CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS is not set
Rebuild; re‑check both the source tree .config
and the installed /boot/config-*
matching the running kernel.
Install / Update wireless‑regdb
git clone git://git.kernel.org/pub/scm/linux/kernel/git/wireless-regdb/wireless-regdb.git
cd wireless-regdb
make # builds regulatory.db (and .p7s if signing configured)
sudo cp regulatory.db /lib/firmware/
# Optional: remove/rename regulatory.db.p7s if signatures disabled
Reload cfg80211 or reboot:
sudo modprobe -r cfg80211
sudo modprobe cfg80211
Validate with iw
World (expected fallback):
iw reg set 00
iw reg get
country 00: DFS-UNSET
(755 - 928 @ 2), (N/A, 20), (N/A), PASSIVE-SCAN
(2402 - 2472 @ 40), (N/A, 20), (N/A)
(2457 - 2482 @ 20), (N/A, 20), (N/A), AUTO-BW, PASSIVE-SCAN
(2474 - 2494 @ 20), (N/A, 20), (N/A), NO-OFDM, PASSIVE-SCAN
(5170 - 5250 @ 80), (N/A, 20), (N/A), AUTO-BW, PASSIVE-SCAN
(5250 - 5330 @ 80), (N/A, 20), (0 ms), DFS, AUTO-BW, PASSIVE-SCAN
(5490 - 5730 @ 160), (N/A, 20), (0 ms), DFS, PASSIVE-SCAN
(5735 - 5835 @ 80), (N/A, 20), (N/A), PASSIVE-SCAN
(57240 - 63720 @ 2160), (N/A, 0), (N/A)
GB After Fixes:
iw reg set GB
iw reg get
country GB: DFS-ETSI
(2400 - 2483 @ 40), (N/A, 20), (N/A)
(5150 - 5250 @ 80), (N/A, 23), (N/A), NO-OUTDOOR, AUTO-BW
(5250 - 5350 @ 80), (N/A, 20), (0 ms), NO-OUTDOOR, DFS, AUTO-BW
(5470 - 5730 @ 160), (N/A, 26), (0 ms), DFS
(5725 - 5850 @ 80), (N/A, 23), (N/A), NO-OUTDOOR
(5925 - 6425 @ 320), (N/A, 23), (N/A), NO-OUTDOOR
(57000 - 71000 @ 2160), (N/A, 40), (N/A)
8. Hostapd Alignment (5 GHz Example)
country_code=GB
ieee80211d=1 # advertise country/reg rules
ieee80211h=1 # DFS + TPC support
hw_mode=a # 5 GHz
channel=36 # choose legal indoor channel
vht_oper_centr_freq_seg0_idx=42 # adjust per bandwidth
If using DFS channels (52+), expect a CAC (Channel Availability Check) holdoff before beacons; logs will show DFS events.
9. Indoor vs Outdoor (UK High‑Level Reference)
- 5150‑5250 MHz (ch 36‑48): Indoor only; typically no DFS.
- 5250‑5350 MHz (ch 52‑64): Indoor only; DFS + TPC.
- 5470‑5725 MHz (ch 100‑140): Indoor/outdoor; DFS mandatory.
- 5725‑5850 MHz (upper 5 GHz): Outdoor under power limits; equipment class dependent.
- 5925‑6425 MHz (6 GHz LPI/VLP evolving): Indoor low power; check current regulator bulletins.
These values track ETSI / Ofcom guidance current at the time of testing; always confirm latest tables.
Decoding Regulatory Flags (iw ↔ cfg80211 ↔ regdb)
Common flags you may see:
iw Flag | Meaning | Kernel Symbol / Note | Operational Impact |
---|---|---|---|
NO-IR | No Initiate Radiation | IEEE80211_CHAN_NO_IR |
Cannot start AP / send beacons; client passive only until permitted. |
DFS | Radar detection required | IEEE80211_CHAN_RADAR / reg RRF_DFS |
CAC before transmit; must vacate on radar. |
NO-OUTDOOR | Indoor restriction | IEEE80211_CHAN_INDOOR_ONLY |
Outdoor AP use prohibited; some drivers enforce tx power caps. |
AUTO-BW | Auto width allowed | width negotiation ok within reg limits | Drivers may widen if clean spectrum. |
PASSIVE-SCAN | Listen only until country set | often world domain fallback | AP mode blocked. |
The full flag set in include/net/cfg80211.h
includes width bans (NO_20MHZ
, NO_10MHZ
), 6 GHz client limits (VLP/AFC), and monitoring overrides. Inspect with grep IEEE80211_CHAN_ include/net/cfg80211.h
.
Platform Notes
FreeBSD Contrast
FreeBSD wireless tools (e.g., ifconfig wlan0 regdomain
, regdomain.xml
) expose indoor/outdoor distinctions explicitly and have historically allowed local administrators to apply regional data more directly. Behaviour differs by driver; nevertheless this transparency helped spot that Linux was quietly reverting.
MT7921 TX Power Field Notes
Some users observed unexpectedly low EIRP (~6 dBi effective) from MEDIATEK MT7921 in Linux compared with vendor firmware or Windows environments. Regulatory fallback and driver caps both contribute; confirm actual tx power with survey tools after correct reg domain loads. (Collect repeatable lab data before drawing final conclusions.)
Powersave & Other cfg80211 Defaults to Revisit
CFG80211_DEFAULT_PS=y
enables STA powersave by default; desirable for clients, not always for AP bridging / test rigs where timing matters. Review also CFG80211_CRDA_SUPPORT
and legacy WEXT toggles if building lean images.
Troubleshooting Quick Table
Symptom | Likely Cause | Check | Fix |
---|---|---|---|
country 00: DFS-UNSET |
regdb rejected / signature gating | `dmesg | grep -i regdb` |
Primary frequency not allowed in hostapd |
NO-IR or DFS blocked under current domain | iw reg get ; iw list |
correct country; wait DFS CAC; choose legal ch |
.config flips options back |
build scripts/defconfig reapply defaults | pre/post build diff | enforce fragment; patch Kconfig |
Low tx power vs spec | indoor flag or driver cap | iw phy txpwr; reg domain |
verify region; driver update |
Compliance & Responsibility
Restoring regional capability is about using spectrum lawfully, not bypassing law. Regulators (Ofcom UK; ETSI EU; FCC US; etc.) mandate power masks, indoor/outdoor splits, radar detection, and sometimes dynamic coordination (AFC). Custom kernels place the compliance burden on the operator. Audit deployments.
The perfect fix for defaults
The sed
command below used on net/wireless/Kconfig
can be applied in many more places and while this will break the kernel build we hope the idea fully understood, if a default exists, find it, remove it!
A much better option is to edit each file as we were once supposed to when reviewing code we are to 'trust' and find the defaults and remove the lines with default n
or default y
and there we have choice restored. Please do not try below unless you are willing to break the kbuild process because it will break!
sed -i 's/default n//g' /usr/src/linux-6.12.30/net/wireless/Kconfig
sed -i 's/default y//g' /usr/src/linux-6.12.30/net/wireless/Kconfig
Conclusion
Linux offers freedom only when that freedom is exercised with knowledge. Kernel defaults protect vendors; they can work against informed operators when those defaults are wrong for the deployment. Audit cfg80211, control your build, deploy an up‑to‑date regulatory database, and verify runtime behaviour with iw
. Do that, and the system returns to its promise: user control within lawful bounds.