FlawOpen

flawopen.com/Teardowns/cve-2024-33066-qualcomm-wlan-log-redirection

● CVE-2024-33066 · CVSS 9.8 · Critical
FlawOpen Security Research

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.

💡 Plain English Explainer (ELI5)

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

Step 1

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.

Step 2

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.

Step 3

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.

Step 4

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.

UNPATCHED FLAW
#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;
}
HARDENED SECURE PATCH
#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

Sources