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

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 showed country 00: DFS-UNSET despite attempts to set GB.
  • hostapd logged Frequency 5180 not allowed for AP mode, Primary frequency not allowed, or IEEE 802.11 Hardware does not support configured channel on otherwise capable radios.
  • .config was manually edited (CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=n), yet after make -j32 the line reappeared as CONFIG_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:

  1. 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.
  2. wireless‑regdb (userspace data project): source of canonical regional channel/power/DFS rules; compiled to regulatory.db consumed by cfg80211.
  3. 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 yn

--- 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.