> ## Content Index
> Fetch the complete content index at: https://articles.akadata.co.uk/llms.txt
> Use this file to discover other available public pages before exploring further.

# When the Kernel Turns Against You - Linux ≠ Freedom of choice?
- URL: https://articles.akadata.co.uk/when-the-kernel-turns-against-you-linux-freedom-of-choice/
- Published: 2025-07-16T20:04:06.000Z
- Updated: 2025-07-16T20:50:33.000Z
- Author: AKADATA
- Tags: News, wifi, wifi6, wifi7, ax, ac, 80211, wireless-regdb, linux

### 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`

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

```diff
--- 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):

```bash
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:

```bash
# 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:

```text
# 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

```bash
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:

```bash
sudo modprobe -r cfg80211
sudo modprobe cfg80211

```

---

### Validate with `iw`

**World (expected fallback):**

```bash
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:**

```bash
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)

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