FlawOpen

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

● CVE-2024-33066 · CVSS 9.8 · Crítica
Pesquisa · FlawOpen

CVE-2024-33066: falha no log WLAN da Qualcomm

CVE-2024-33066 pode corromper memória ao redirecionar logs para um caminho escolhido no WLAN Resource Manager da Qualcomm. Corrigida em out. 2024.

💡 Explicação em Linguagem Simples (ELI5)

Imagine a recepção de um hotel que deixa qualquer pessoa ligar e dizer: "de agora em diante, mande cópias do livro de hóspedes para este endereço". O recepcionista copia o que a pessoa dita num cartãozinho, mesmo quando o texto transborda do cartão para a mesa, e depois manda as cópias para onde estiver escrito, inclusive o cofre do gerente. A correção é aceitar só um rótulo curto que nomeie uma gaveta da sala de arquivos.

Conceitos Centrais e Termos

WLAN Resource Manager
O componente de Wi-Fi citado no aviso da Qualcomm sobre a CVE-2024-33066. Ele roda nas plataformas de rede da Qualcomm, usadas em roteadores, sistemas mesh e pontos de acesso.
Chipsets IPQ / QCN
Famílias de system-on-chip de rede Wi-Fi da Qualcomm. A lista afetada inclui IPQ5332, IPQ8074A, IPQ9574, QCN9000 e as plataformas Immersive Home, não chipsets de celular.
CWE-20
Validação de entrada inadequada: o software confia na entrada sem verificar se ela tem as propriedades de que o código depende, como um tamanho máximo ou um diretório permitido.
Abertura relativa a diretório
Abrir um arquivo com openat() a partir de um descritor de diretório, usando um nome simples sem '/', para que o resultado não possa cair fora desse diretório.
Vetor CVSS 3.1
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H: acessível pela rede, baixa complexidade, sem privilégios nem interação do usuário e alto impacto nas três propriedades (nota 9.8).

Mapeamentos de frameworks

  • Referência CWE para a fraqueza descrita neste guia: CWE-20

Análise de Causa Raiz

O aviso da Qualcomm diz apenas que o WLAN Resource Manager sofria corrupção de memória "while redirecting log file to any file location with any file name" (CWE-20). O destino enviado junto com um pedido de redirecionamento de log era usado sem verificar o tamanho nem para onde apontava. O código abaixo modela essa falha de validação; é ilustrativo e não é código-fonte da Qualcomm.

Fluxo de Ataque Passo a Paso

Passo 1

1. Chega um pedido de redirecionamento de log

O WLAN Resource Manager aceita um pedido para enviar a saída de log para outro lugar. O vetor CVSS (AV:N/PR:N/UI:N) classifica a falha como acessível pela rede, sem privilégios nem interação do usuário.

Passo 2

2. Qualquer local e qualquer nome são aceitos

Segundo a descrição da Qualcomm, o redirecionamento funcionava para qualquer local e com qualquer nome de arquivo: o destino pedido não era verificado quanto ao tamanho nem quanto ao lugar para onde apontava.

Passo 3

3. A entrada não verificada corrompe a memória

No modelo abaixo, um nome maior que o buffer fixo de caminho o ultrapassa (strcpy), e qualquer caminho, inclusive arquivos de configuração, pode ser aberto para escrita. A Qualcomm não publicou qual desses casos ocorreu no seu código.

Passo 4

4. Impacto e situação

O CVSS 3.1 classifica como alto o impacto em confidencialidade, integridade e disponibilidade (9.8). A Qualcomm entregou a correção aos fabricantes no boletim de outubro de 2024; a triagem da CISA não registra exploração conhecida.

Código-Fonte: Vulnerável vs. Seguro

Modelo ilustrativo da classe de vulnerabilidade, não é código da Qualcomm. O handler reforçado limita a entrada com strnlen antes de usá-la, aceita só um nome curto de um conjunto fixo de caracteres (sem '/', sem '.' no início) e o abre com openat() relativo a um diretório de logs escolhido na inicialização, com O_NOFOLLOW para que um symlink plantado não desvie a escrita. Quem chama pode escolher o nome do arquivo, mas nunca o local, e entradas grandes demais são rejeitadas em vez de copiadas.

IMPLEMENTAÇÃO VULNERÁVEL
#include <fcntl.h>
#include <string.h>

#define LOG_PATH_MAX 64

struct rm_log_cfg {
    char path[LOG_PATH_MAX];
    int fd;
};

/* Trata uma solicitação de "redirecionamento de log"; `requested` vem do corpo da solicitação. */
int rm_set_log_destination(struct rm_log_cfg *cfg, const char *requested)
{
    strcpy(cfg->path, requested);   /* sem verificação de tamanho: uma entrada longa ultrapassa path[] */
    cfg->fd = open(cfg->path, O_WRONLY | O_CREAT | O_APPEND, 0644);  /* qualquer local */
    return cfg->fd < 0 ? -1 : 0;
}
PATCH SEGURO E ROBUSTO
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

#define LOG_NAME_MAX 32

struct rm_log_cfg {
    int dir_fd;                /* diretório fixo de logs, aberto uma vez na inicialização */
    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;          /* rejeita '/', impedindo que o nome saia de 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;
}

Lista de Verificação de Segurança para Engenharia

Fontes