Android WLAN: A Journey From QCACLD to SCSC

Steven Salerno (Android Security Researcher · Qualcomm)

DistrictCon 2026 (Year 1) · Day 2 · Mainstage

Overview

In this DistrictCon talk, "Android WLAN: A Journey From QCACLD to SCSC," Steven Salerno, an Android Security Researcher formerly of Qualcomm, delves into the often-overlooked and consistently vulnerable landscape of Wireless LAN (WLAN) drivers within the Android ecosystem. Drawing upon a decade of experience, Salerno provides a comprehensive look at the evolution of Qualcomm's WLAN host drivers, from legacy versions like Primo to the contemporary QCACLD 3.0, and then pivots to a critical analysis of Samsung's own WLAN driver implementations. The core of his presentation highlights the pervasive security flaws stemming from improper handling of the Netlink attribute buffers (NLAs) used by the cfg80211 interface, a modern replacement for older wireless extensions.

Watch on YouTube

Visual summary for Android WLAN: A Journey From QCACLD to SCSC by Steven Salerno
Visual summary for Android WLAN: A Journey From QCACLD to SCSC by Steven Salerno

Key moments

  1. 0:00 Introduction to Android WLAN drivers & attack surface
  2. 8:00 Understanding cfg80211 and Netlink attribute buffers
  3. 26:00 Qualcomm vulnerability: Nested NLA buffer overflow example
  4. 31:00 Samsung WLAN driver: A "field day" for bugs
  5. 38:00 Egregious Samsung bugs, bad patches, and VRP challenges
  6. 44:00 Navigating VRPs: Qualcomm vs. Samsung programs
  7. 48:00 Q&A: Netlink interface capabilities and hardware requirements

Android WLAN: A Journey From QCACLD to SCSC

Speakers: Steven Salerno, Android Security Researcher, Qualcomm

Conference: DistrictCon

YouTube: https://www.youtube.com/watch?v=0PNBq_2IPc

Overview

In this DistrictCon talk, "Android WLAN: A Journey From QCACLD to SCSC," Steven Salerno, an Android Security Researcher formerly of Qualcomm, delves into the often-overlooked and consistently vulnerable landscape of Wireless LAN (WLAN) drivers within the Android ecosystem. Drawing upon a decade of experience, Salerno provides a comprehensive look at the evolution of Qualcomm's WLAN host drivers, from legacy versions like Primo to the contemporary QCACLD 3.0, and then pivots to a critical analysis of Samsung's own WLAN driver implementations. The core of his presentation highlights the pervasive security flaws stemming from improper handling of the Netlink attribute buffers (NLAs) used by the cfg80211 interface, a modern replacement for older wireless extensions.

Salerno’s research, much of which was conducted in his free time, aims to demystify this complex attack surface, making it accessible to aspiring security researchers and bug bounty hunters. He demonstrates how fundamental programming errors, particularly a lack of robust input validation and inconsistent use of kernel-provided security primitives, lead to a plethora of exploitable vulnerabilities, including buffer overflows and information leaks. The talk serves as both an educational resource on a critical, yet under-audited, kernel attack surface and a stark warning about the persistent "dumpster fire" state of WLAN security across major Android vendors.

The presentation not only exposes specific technical weaknesses but also offers a critical commentary on the systemic issues within product security teams, such as understaffing, lack of proactive code review, and the fragmentation of security reporting mechanisms across large corporations like Samsung. By dissecting real-world CVEs and contrasting the security postures of Qualcomm and Samsung, Salerno underscores the urgent need for more rigorous development practices and a unified approach to vulnerability management in the ubiquitous world of mobile connectivity.

Background

▶ Watch: Introduction to Android WLAN drivers & attack surface (0:00)

The journey into Android WLAN security begins with understanding the historical context and the underlying architecture of these critical components. Steve Salerno's research commenced a decade ago at Qualcomm, where he focused on the WLAN host driver. On Linux, Qualcomm's WLAN drivers have evolved through several iterations: the largely deprecated Primo driver, the minimal QCACLD 2.0 for low-end devices, and the currently prevalent QCACLD 3.0 found in high-tier flagship products. These host drivers interact with various firmware variants, dependent on the specific WLAN chip hardware.

The attack surface for these drivers is multifaceted, encompassing typical Linux kernel interfaces like sysfs, procfs, and debugfs, alongside ioctls (historically known as wireless extensions). However, a particularly critical and unique attack vector for WLAN drivers is Over-The-Air (OTAA) attacks. These are the "holy grail" for offensive security researchers, aiming for zero-click, remote pre-authentication kernel code execution. While the host driver itself processes limited OTAA data, much of it is passed up the stack to user-space components like WPA supplicant. Nevertheless, OTAA attacks can directly target the WLAN firmware, as demonstrated by past vulnerabilities like Broadpwn, enabling pivots from the WLAN chip to the application processor via mechanisms such as DMA or PCIe.

Salerno presented a revealing chart illustrating 10 years of WLAN issues, categorizing them by host driver (blue) and firmware (red). He highlighted several crucial caveats: prior to a significant red spike in the data, Qualcomm did not issue its own security bulletins, with Google aggregating and reporting generic "Qualcomm closed source component" bugs. This historical opacity, coupled with the fact that many internal issues never see public disclosure, means the presented data is an undercount of the true number of vulnerabilities. This context underscores the persistent and often hidden nature of security flaws in WLAN components, setting the stage for the deep dive into cfg80211, the modern interface that has replaced the older wireless extensions.

Key Findings

▶ Watch: Qualcomm vulnerability: Nested NLA buffer overflow example (26:00)

Steven Salerno's research uncovered a widespread pattern of critical vulnerabilities, primarily buffer overflows and overreads, across Android WLAN drivers, particularly those implemented by Samsung. His key findings can be summarized as follows:

  1. Systemic Vulnerabilities in cfg80211 Implementation: The core problem lies in the improper and inconsistent adoption of the cfg80211 interface and its underlying Netlink attribute buffers (NLAs). While cfg80211 was designed to replace older, less secure wireless extensions, many vendor implementations, especially Samsung's, fail to utilize the inherent security mechanisms provided by the kernel.
  2. Lack of NLA Policy Validation: A primary vulnerability source is the absence of NLA policies during the parsing of Netlink attribute buffers. Qualcomm's QCACLD 3.0 driver, while still having bugs, generally employs these policies to enforce type and length checks on incoming attributes. In stark contrast, Samsung's WLAN driver implementations largely forgo NLA policies, leading to a "shooting fish in a barrel" scenario where almost every command handler is susceptible to trivial input validation errors.
  3. Prevalence of Trivial Buffer Overflows and Overreads: Salerno demonstrated multiple instances where user-controlled lengths or indices led directly to memory corruption. Examples included:
  • An integer overflow in num_chan (a uint8) within a Qualcomm roam_vendor_command handler, allowing an attacker to specify 256 channels, causing the num_chan counter to wrap to 0, bypass a bounds check (e.g., < 96), and then trigger a buffer overflow during a subsequent data copy loop.
  • Numerous Samsung bugs involving direct use of user-supplied U16 length values in memcpy operations without proper bounds checking against the allocated buffer size. These are described as "brain-dead buffer overflows" reminiscent of basic computer security 101 examples.
  • Array index out-of-bounds writes (e.g., writing zero to array[index] where index is user-controlled and unchecked).
  • Null-termination issues in string handling, leading to buffer overreads and overflows when standard C string functions operate on untrusted, non-null-terminated input.
  1. Security Reporting and Patching Disconnects: Salerno highlighted significant challenges in the vulnerability disclosure and patching process, particularly with Samsung. The fragmentation of Samsung's security teams into "Samsung Mobile Security" and "Samsung Semiconductor Product Security" (which are effectively different corporations) leads to researchers missing critical security bulletins and patches. This organizational disconnect, combined with inconsistent patching quality (e.g., patches fixing one instance of a bug but missing identical logic nearby, or applying checks based on irrelevant attributes), contributes to the persistence of vulnerabilities.
  2. Under-Audited Attack Surface: The cfg80211 interface remains largely unexamined by researchers, fuzzer tools, and static analysis, making it a rich source of "low-hanging fruit." Its complexity, especially with nested attributes and diverse parsing APIs, often leads developers to overlook validation requirements.

These findings collectively paint a picture of a critical, yet neglected, attack surface ripe for exploitation, primarily due to fundamental security engineering failures rather than complex logic bugs.

Technical Deep Dive

▶ Watch: Samsung WLAN driver: A "field day" for bugs (31:00)

The technical core of Salerno's talk revolves around the cfg80211 interface and its use of Netlink attribute buffers (NLAs), contrasting their implementation quality between Qualcomm and Samsung.

Netlink Attribute Buffers (NLAs): The Foundation

The Linux wireless community transitioned from wireless extensions (using ioctls) to cfg80211 (using Netlink) for configuring WLAN devices. Netlink is a kernel interface for inter-process communication, and cfg80211 leverages it by sending NLAs. These are essentially Length-Type-Value (TLV) structures. A struct nlattr in the kernel defines the basic unit: nla_len (a U16 for the attribute's length) and nla_type. A key complexity is the ability to nest NLAs, meaning the value field of one attribute can itself contain another full NLA buffer. This "inception-level" nesting significantly complicates input validation, requiring checks at every layer.

Core NLA Parsing APIs and Their Pitfalls

Salerno highlighted several common kernel APIs for NLA parsing:

  • nla_data(): Returns a pointer to the attribute's payload buffer.
  • nla_len(): Returns the length of the attribute. Crucially, while the internal nla_len field is a U16, the nla_len() function returns an int. This detail can be important for integer overflow analysis, as the maximum attribute size is capped by U16_MAX.
  • nla_get_U32() (and similar nla_get_* accessors): These functions retrieve data of a specific type (e.g., U32, U8). A critical flaw is that these functions do not perform size validation. If a developer calls nla_get_U32() on an attribute that only contains two bytes of data, the function will simply cast the data pointer to a U32* and dereference it, potentially leading to an out-of-bounds read if the buffer is too small.
  • nla_memcpy() and nla_memcmp(): nla_memcpy() is generally safer as it compares the requested copy length against the actual attribute length, preventing simple buffer overflows if used correctly.

NLA Parsing Functions: nla_parse vs. nla_for_each_attr

The choice of parsing function significantly impacts vulnerability potential:

  • nla_parse(): This function takes an NLA buffer and an optional NLA policy. It constructs a dictionary-like structure where attribute types are keys and pointers to their payloads are values. A critical side effect is that if an attacker provides multiple attributes of the same type, nla_parse() will only store the last one.
  • nla_for_each_attr() (and nla_parse_nested()): These are macros that iterate through all attributes in a buffer, regardless of type duplication. This can lead to Time-of-Check, Time-of-Use (TOCTOU) vulnerabilities if a developer performs a check based on an attribute's value in one iteration, but a subsequent iteration (or a different parsing method) modifies that value.

NLA Policy: The Unsung Hero (and Samsung's Neglect)

The NLA policy is an optional but vital argument to nla_parse(). It allows developers to define expected types and lengths for attributes. Salerno detailed various policy types:

  • NLA_NUL_STRING: Guarantees null termination, with the null byte counted in the policy's length.
  • NLA_STRING: No null termination guarantee.
  • NLA_NUL_STRING, NLA_STRING, NLA_BINARY: Policy length specifies a maximum allowed length.
  • NLA_UNSPEC: The default type. If a length is specified in the policy for NLA_UNSPEC, it acts as a minimum required length. This is crucial for fixed-size data like MAC addresses (e.g., 6 bytes).

Salerno explicitly stated that Qualcomm's QCACLD 3.0 driver extensively uses NLA policies, making bug finding significantly harder. In stark contrast, Samsung's WLAN driver implementations largely omit NLA policies, which directly leads to the "shooting fish in a barrel" scenario.

Qualcomm Example: NL80211_CMD_START_AP and Vendor Commands

In a start_ap command handler, Qualcomm's code demonstrates good practices:

  1. It receives an already parsed genl_info structure from the core kernel.
  2. It explicitly checks for the presence of mandatory attributes (beacon_interval, dtim_period, beacon_head).
  3. It uses nla_get_u8() for smps_mode and validates its value against sane limits.
  4. Data is then passed to a generic wrapper (rdev_start_ap) for firmware processing.

For vendor-specific functionality, the NL80211_CMD_VENDOR command is used. This command takes a vendor_id and vendor_subcommand to locate a specific vendor-defined callback. The actual data for the vendor command is passed in a nested vendor_data attribute. In a Qualcomm vendor command example (set_tx_power_scale_decrement_db), the handler correctly calls nla_parse() on the nested vendor_data and, critically, supplies a dedicated NLA policy (tx_power_scale_decb_policy) for validation.

Qualcomm Bug Example: roam_vendor_command (CVE-XXXX-XXXX)

Salerno detailed a real bug he reported in Qualcomm's roam_vendor_command handler. This nested command involved multiple layers of nla_parse and policy-based validation. The vulnerability arose in a section designed to process a list of frequencies (param_scan_freq_list).

  1. An nla_for_each_nested macro was used to iterate through these frequency attributes, incrementing a num_chan variable (defined as a uint8).
  2. A bounds check followed: if (num_chan > MAX_VALUE) (e.g., 96), it would error out.
  3. The Bug: By sending 256 param_scan_freq_list attributes, num_chan would integer overflow from 255 to 0.
  4. The bounds check 0 > 96 would pass.
  5. A second nla_for_each_nested loop was then used to copy the data, but it would iterate through all 256 attributes, writing past the end of an array allocated for MAX_VALUE channels, resulting in a buffer overflow.

The fix involved consolidating the loops and adding a sanity check within the loop to bail out if num_chan exceeded MAX_VALUE.

Samsung's "Brain-Dead" Buffer Overflows

Samsung's WLAN driver code, in stark contrast, consistently exhibits basic input validation failures. Salerno showcased a particularly egregious example (CVE credited to another researcher, but Salerno identified its root cause and similar instances):

  1. An nla_for_each_attr loop processed an attribute attr_app_info_lang.
  2. The U16 value of this attribute was read into a length variable.
  3. Immediately after, a memcpy() was called, using this user-controlled length to copy data into a fixed-size buffer.

This is a textbook heap buffer overflow (or stack, depending on context) where the destination buffer's size is not checked against the source length, which is directly controlled by the attacker. Salerno found this primitive repeated verbatim in multiple places, often with flawed or incomplete patches that either missed adjacent instances or used length checks from entirely unrelated attributes. For example, one patch used a length check for sda_service_specific_info_lang when copying data related to publish_surface_info, rendering the patch ineffective.

This technical deep dive reveals that while the Netlink interface itself provides powerful and flexible communication, its security hinges entirely on diligent and correct implementation, particularly concerning input validation and the use of NLA policies. When these are neglected, even basic programming errors can lead to critical kernel-level vulnerabilities.

Demo / Proof of Concept

▶ Watch: Navigating VRPs: Qualcomm vs. Samsung programs (44:00)

While Steven Salerno's talk did not feature a live, interactive demonstration of an exploit, he thoroughly walked through the conceptual proof-of-concept for several critical vulnerabilities. The most detailed example was the integer overflow leading to a buffer overflow in Qualcomm's roam_vendor_command handler.

The proof-of-concept for this specific bug would involve crafting a malicious Netlink message for the NL80211_CMD_VENDOR command. Within this vendor command, the vendor_data attribute would contain a nested NLA buffer. This nested buffer would specify the roam_vendor_command subcommand and, critically, include 256 instances of the param_scan_freq_list attribute.

When this crafted message is processed by the vulnerable kernel code:

  1. The nla_for_each_nested macro would iterate through the 256 param_scan_freq_list attributes.
  2. The num_chan variable, a uint8, would increment from 0 up to 255, and then overflow back to 0.
  3. A subsequent bounds check, if (num_chan > MAX_VALUE) (e.g., if (num_chan > 96)), would evaluate to 0 > 96, which is false, thus bypassing the validation.
  4. A second nla_for_each_nested loop, intended to copy the frequency list data into an array, would then iterate over all 256 attributes (as num_chan was no longer used as the loop bound), attempting to copy far more data than the array's allocated size (e.g., 96 entries). This would result in a heap buffer overflow, allowing an attacker to write controlled data beyond the intended buffer.

Similarly, the "brain-dead" Samsung buffer overflows would be demonstrated by sending a Netlink message containing a U16 attribute (e.g., attr_app_info_lang) with an arbitrarily large value, followed by data. The vulnerable memcpy call, using this unchecked U16 as its length argument, would then write data far beyond the bounds of its intended destination buffer.

These conceptual demonstrations highlight how seemingly trivial input validation errors, when combined with specific data structures and kernel APIs, can lead to powerful memory corruption primitives that are ripe for exploitation.

Defensive Implications

▶ Watch: Q&A: Netlink interface capabilities and hardware requirements (48:00)

The detailed analysis of WLAN driver vulnerabilities by Steven Salerno offers crucial insights for defenders aiming to secure Android devices. The implications span development practices, code auditing, and vulnerability management:

  1. Mandate NLA Policy Usage: The most immediate and impactful defensive measure is for all developers working with cfg80211 and Netlink attribute buffers to mandate the use of NLA policies during nla_parse operations. As demonstrated by Qualcomm's generally more robust (though not perfect) code, NLA policies provide essential type and length validation, drastically reducing the likelihood of common buffer overflows and type confusion issues. Without policies, every attribute parsing becomes a potential vulnerability.
  2. Rigorous Input Validation at All Levels: Beyond NLA policies, developers must implement explicit and comprehensive input validation at every stage of data processing, especially when dealing with nested attributes. Each layer of nesting introduces new opportunities for validation to be missed. Specific checks should include:
  • Verifying attribute presence for mandatory fields.
  • Bounds checking all user-supplied lengths and indices against allocated buffer sizes.
  • Ensuring null termination for strings before using standard C string functions.
  • Sanity checking enum or flag values against known, acceptable ranges.
  1. **Audit nla_for_each_attr and nla_get_* APIs:** Security teams should prioritize auditing code paths that use nla_for_each_attr (or nla_parse_nested) and nla_get_* accessors. nla_for_each_attr can lead to TOCTOU issues if subsequent logic relies on attribute values remaining static after initial checks. nla_get_* calls are dangerous without prior length validation, as they perform unchecked casts and dereferences.
  2. Proactive Static Analysis and Fuzzing: The cfg80211 interface is an "under-audited attack surface." Integrating static analysis tools configured to detect common memory safety errors (e.g., buffer overflows, integer overflows, use-after-free) in Netlink handlers is critical. Furthermore, kernel fuzzing specifically targeting the cfg80211 interface, potentially by generating malformed Netlink messages with nested attributes and out-of-bounds lengths/types, would likely uncover a significant number of vulnerabilities, as the talk suggests.
  3. Improved Internal Security Processes: For large organizations like Samsung, the fragmentation of security teams and inconsistent vulnerability management processes are major weaknesses. Defenders need to advocate for:
  • Unified security reporting and patching mechanisms across all product divisions.
  • Cross-team code review and knowledge sharing, especially for common components like WLAN drivers.
  • Proactive security engineering engagement to enforce secure coding standards (like NLA policies) rather than reactive bug fixing.
  • Thorough patch analysis to ensure fixes are comprehensive and don't miss adjacent or similar vulnerabilities.
  1. Consider Capabilities and Privilege Separation: While many of these bugs result in root-to-kernel escalation, it's important to remember that components like WPA supplicant operate with elevated but non-root privileges. Exploiting a cfg80211 vulnerability from a less privileged context could still lead to a privilege escalation to kernel code execution. Therefore, strict adherence to the principle of least privilege for WLAN-related daemons is essential.
  2. Address Third-Party Driver Security: The challenges of reporting and patching bugs in third-party drivers (e.g., Broadcom) highlight a systemic industry problem. OEMs and platform providers should establish clearer channels and responsibilities for addressing vulnerabilities in these critical components.

By adopting these defensive strategies, organizations can move beyond simply patching individual bugs and instead build a more resilient and secure WLAN driver ecosystem, addressing the root causes of these persistent vulnerabilities.

Key Takeaways

  • WLAN drivers remain a critical and vulnerable attack surface: Despite years of research and patching, WLAN components, especially kernel host drivers and firmware, are still prone to significant security flaws, often due to fundamental input validation errors.
  • The cfg80211 interface is a neglected goldmine for bugs: The modern Netlink-based cfg80211 interface, intended to replace older wireless extensions, is poorly understood and under-audited by many developers and security researchers, leading to a wealth of "low-hanging fruit" vulnerabilities.
  • NLA Policy usage is paramount for secure Netlink parsing: The consistent application of NLA policies during nla_parse operations is the single most effective defense against common buffer overflows and other memory safety issues in Netlink attribute buffer processing. Its absence, as seen in Samsung's drivers, directly leads to widespread vulnerabilities.
  • Trivial programming errors lead to critical kernel exploits: Many discovered vulnerabilities are basic, "computer security 101" buffer overflows and integer overflows, stemming from unchecked user-controlled lengths or indices in memcpy and array access operations.
  • Organizational and patching challenges exacerbate WLAN security: Fragmented security teams, inconsistent vulnerability reporting, and inadequate patch quality (e.g., incomplete fixes or misapplied checks) significantly hinder the overall security posture of complex software stacks like Android's WLAN.
  • Broadcom and other Samsung drivers are prime targets for future research: Given the prevalence of issues and the relative lack of scrutiny, Broadcom drivers (despite reporting difficulties) and further Samsung WLAN driver codebases are likely to contain more unaddressed vulnerabilities, offering opportunities for new research and bug bounties.

About the Speaker(s)

Steven Salerno is an experienced Android Security Researcher, currently affiliated with Qualcomm. With a career spanning over a decade in the field, Salerno previously worked on the QPSI (Product Security) team at Qualcomm, where he spent approximately a year and a half focusing specifically on WLAN host drivers. His expertise lies in uncovering and analyzing security vulnerabilities within complex, low-level system components like kernel drivers. Salerno's research, often conducted in his free time, aims to contribute to the broader security community by dissecting under-audited attack surfaces and sharing insights to help new researchers find their first bug or bounty. His deep understanding of Android's internal workings and kernel-level security makes him a prominent voice in mobile security research.

Reviews

Dr. Zero (Offensive Security Researcher) — SOLID

Solid, practitioner-focused breakdown of a genuinely under-audited attack surface. Salerno delivers exactly what he promises: a roadmap for finding trivial kernel bugs in WLAN drivers, with real CVEs and a clear contrast between Qualcomm's middling-but-improving hygiene and Samsung's apparent indifference to NLA validation. Not novel in the 'new technique' sense, but highly actionable for anyone who wants to start hunting in this space.

Heather Calloway (CISO) — STRONG ACCEPT

This is the kind of technical research that changes how I think about mobile fleet risk. Not because I'll patch WLAN drivers myself, but because it demonstrates that a major vendor's kernel attack surface is riddled with CS-101 buffer overflows — and their security org can't consistently fix them. That's a procurement and vendor management problem, not just a bug.

→ Top-rated talks at DistrictCon 2026 (Year 1)

All talks from DistrictCon 2026 (Year 1)