AP mode PMF disconnection protection bypass
Published: September 11, 2019
Identifiers:
- CVE-2019-16275
Latest version available from: https://w1.fi/security/2019-7/
Vulnerability
hostapd (and wpa_supplicant when controlling AP mode) did not perform
sufficient source address validation for some received Management frames
and this could result in ending up sending a frame that caused
associated stations to incorrectly believe they were disconnected from
the network even if management frame protection (also known as PMF) was
negotiated for the association. This could be considered to be a denial
of service vulnerability since PMF is supposed to protect from this type
of issues. It should be noted that if PMF is not enabled, there would be
no protocol level protection against this type of denial service
attacks.
An attacker in radio range of the access point could inject a specially
constructed unauthenticated IEEE 802.11 frame to the access point to
cause associated stations to be disconnected and require a reconnection
to the network.
Vulnerable versions/configurations
All hostapd and wpa_supplicants versions with PMF support
(CONFIG_IEEE80211W=y) and a runtime configuration enabled AP mode with
PMF being enabled (optional or required). In addition, this would be
applicable only when using user space based MLME/SME in AP mode, i.e.,
when hostapd (or wpa_supplicant when controlling AP mode) would process
authentication and association management frames. This condition would
be applicable mainly with drivers that use mac80211.
Possible mitigation steps
- Merge the following commit to wpa_supplicant/hostapd and rebuild:
AP: Silently ignore management frame from unexpected source address
This patch is available from https://w1.fi/security/2019-7/
- Update to wpa_supplicant/hostapd v2.10 or newer, once available
This will avoid breaking the build whenever a non-major kernel update
happens. In the update script, we map each kernel version to the latest
patch for the latest kernel version less than or equal to what we
have packaged.
As far as I can tell, this has never defaulted to on upstream, and our
common kernel configuration doesn't turn it on, so the attack surface
reduction here is somewhat homeopathic.
This is an updated version of the former upstream,
https://github.com/AndroidHardeningArchive/linux-hardened, and provides
a minimal set of additional hardening patches on top of upstream.
The patch already incorporates many of our hardened profile defaults,
and releases are timely (Linux 5.5.15 and 5.6.2 were released on
2020-04-02; linux-hardened patches for them came out on 2020-04-03 and
2020-04-04 respectively).
We don't currently have tests to ensure it works and keeps working.
So instead of having it accidentially working, and possibly breaking it
in the future, disable it for now.
The previous patch just removed a `ConditionFileNotEmpty=…` line from
`kmod-static-nodes.service` referring to a location not existing on
NixOS. We know better, and can actually replace this Condition to point
to `run/booted-system/kernel-modules/lib/modules/%v/`, instead of just
patching it out.
This was simply undoing a hunk from
0008-Don-t-try-to-unmount-nix-or-nix-store.patch, so drop that one from
there and omit
0017-Fix-mount-option-x-initrd.mount-handling-35268-16.patch entirely.
These patches removed logic in the meson install phase invoking
`journalctl --update-catalog` and `systemd-hwdb update`, which would
mutate the running system, and obviously fails in the sandbox.
Upstream also knows this is a bad thing if you're not on the machine you
want to deploy to, so there's logic in there to not execute it when
DESTDIR isn't empty. In our case, it is - as we set --prefix instead for
other reasons, but by just setting DESTIDIR to "/", we can still trigger
these things to be skipped.
The patches removed some context from
0018-Install-default-configuration-into-out-share-factory.patch, which
we need to introduce there to make that patch still apply.
After patching, this produces exactly the same source code as in our
custom fork, but having the actual patches inlined inside nixpkgs makes
it easier to get rid of them.
In case more complicated rebasing is necessary, maintainers can
- Clone the upstream systemd/systemd[-stable] repo
- Checkout the current rev mentioned in src
- Apply the patches from this folder via `git am 00*.patch`
- Rebase the repo on top of a new version
- Export the patch series via `git format-patch $newVersion`
- Update the patches = [ … ] attribute (if necessary)