flawopen.com/Teardowns/cve-2024-33066-qualcomm-wlan-log-redirection
CVE-2024-33066: Qualcomm WLAN log redirection flaw
CVE-2024-33066 can corrupt memory when Qualcomm’s WLAN Resource Manager redirects logs to a caller-selected path. Fixed in Oct. 2024.
Imagine a hotel front desk that lets any caller say 'from now on, send copies of the guest book to this address'. The clerk copies whatever the caller dictates onto a small index card, even when it runs off the card onto the desk, and then sends the copies wherever it says, including the manager's safe. The fix is to accept only a short label that names a drawer in the records room.
Core Concepts & Subsystem Terms
WLAN Resource Manager- The Wi-Fi component named in Qualcomm's advisory for
CVE-2024-33066. It runs on Qualcomm's networking platforms, which are used in routers, mesh systems and access points. IPQ / QCN chipsets- Qualcomm's Wi-Fi networking system-on-chip families. The affected list includes IPQ5332, IPQ8074A, IPQ9574, QCN9000 and Immersive Home platforms, not phone chipsets.
CWE-20- Improper Input Validation: the software trusts input without checking that it has the properties the code relies on, such as a maximum length or an allowed directory.
Directory-relative open- Opening a file with
openat()against a directory descriptor, using a plain name with no '/', so the result cannot land outside that directory. CVSS 3.1 vector- AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H: network-reachable, low complexity, no privileges or user interaction, high impact on all three properties (score 9.8).
Framework mappings
- CWE reference for the weakness described in this guide: CWE-20
Root Cause Analysis
Qualcomm's advisory says only that the WLAN Resource Manager suffered memory corruption "while redirecting log file to any file location with any file name" (CWE-20). The destination supplied with a log redirection request was used without checking its length or where it pointed. The code below models that input-validation gap; it is illustrative and is not Qualcomm source code.
Step-by-Step Attack Flow
1. A log redirection request arrives
The WLAN Resource Manager accepts a request to send its log output somewhere else. The CVSS vector (AV:N/PR:N/UI:N) rates the flaw as reachable over the network without privileges or user interaction.
2. Any location and any name are accepted
Qualcomm's description says the redirect worked 'to any file location with any file name': the requested destination was not checked for length or for where it pointed.
3. Unchecked input corrupts memory
In the model below, a name longer than the fixed path buffer overruns it (strcpy), and any path, including configuration files, can be opened for writing. Qualcomm has not published which of these occurred in its code.
4. Impact and status
CVSS 3.1 rates confidentiality, integrity and availability impact as high (9.8). Qualcomm shipped the fix to device makers in its October 2024 bulletin; CISA's triage records no known exploitation.
Source Code: Flaw vs. Secure Implementation
Illustrative model of the vulnerability class, not Qualcomm code. The hardened handler bounds the input with strnlen before touching it, accepts only a short name from a fixed character set (no '/', no leading '.'), and opens it with openat() relative to a log directory chosen at start-up, with O_NOFOLLOW so a planted symlink cannot redirect the write. The caller can choose a file name but never a location, and oversized input is rejected instead of copied.
#include <fcntl.h>
#include <string.h>
#define LOG_PATH_MAX 64
struct rm_log_cfg {
char path[LOG_PATH_MAX];
int fd;
};
/* Handles a "redirect log" request; `requested` comes from the request body. */
int rm_set_log_destination(struct rm_log_cfg *cfg, const char *requested)
{
strcpy(cfg->path, requested); /* no length check: long input overruns path[] */
cfg->fd = open(cfg->path, O_WRONLY | O_CREAT | O_APPEND, 0644); /* any location */
return cfg->fd < 0 ? -1 : 0;
}
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#define LOG_NAME_MAX 32
struct rm_log_cfg {
int dir_fd; /* fixed log directory, opened once at start-up */
char name[LOG_NAME_MAX];
int fd;
};
static int valid_log_name(const char *name, size_t len)
{
if (len == 0 || len >= LOG_NAME_MAX || name[0] == '.')
return 0;
for (size_t i = 0; i < len; i++) {
char c = name[i];
int ok = (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
c == '-' || c == '_' || c == '.';
if (!ok)
return 0; /* rejects '/', so the name cannot leave dir_fd */
}
return 1;
}
int rm_set_log_destination(struct rm_log_cfg *cfg, const char *requested)
{
size_t len = strnlen(requested, LOG_NAME_MAX);
if (!valid_log_name(requested, len))
return -EINVAL;
int fd = openat(cfg->dir_fd, requested,
O_WRONLY | O_CREAT | O_APPEND | O_NOFOLLOW | O_CLOEXEC, 0600);
if (fd < 0)
return -errno;
memcpy(cfg->name, requested, len + 1);
if (cfg->fd >= 0)
close(cfg->fd);
cfg->fd = fd;
return 0;
}
Engineering & System Hardening Checklist
- ✓In CI, call rm_set_log_destination with a 64-character name, '../etc/passwd', '/tmp/x', '.hidden' and a name containing '/', and assert each returns -EINVAL without creating a file.
- ✓Fail CI on new strcpy or sprintf calls that write request fields into fixed-size buffers (for example with a semgrep or clang-tidy rule); require an explicit bound such as strnlen or snprintf.
- ✓Resolve every caller-selectable output file with
openat()against a directory descriptor opened at start-up, and pass O_NOFOLLOW so a name can never escape that directory. - ✓Inventory routers and access points built on IPQ/QCN chipsets, confirm their firmware includes Qualcomm's October 2024 fix, and keep management and diagnostic interfaces on an administrative network.