CVE-2026-19595 in Zephyr
Sumário
de VulDB • 20/10/2026
O verificador de syscall em modo usuário, z_vrfy_rtio_cqe_get_mempool_buffer() em subsys/rtio/rtio_syscalls.c, validava seus dois parâmetros de saída, buff e buff_len, com K_SYSCALL_MEMORY_READ(), ao invés de K_SYSCALL_MEMORY_WRITE(). Ambos são puramente parâmetros de saída: z_impl_rtio_cqe_get_mempool_buffer() armazena o endereço do buffer da mempool e seu comprimento através deles. A distinção é imposta por cada validador de arquitetura — arch_buffer_validate() no RISC-V PMP aceita explicitamente apenas as regiões globais __rom_region/__rodata_region para leituras, e os validadores ARM MPU aceitam regiões P_RO_U_RO e P_RW_U_RO exclusivamente para leitura — portanto, um ponteiro validado como legível não é necessariamente gravável pela thread chamadora.
Uma thread em modo usuário sem privilégios que tenha recebido acesso a um contexto RTIO (rtio_access_grant()) pode invocar o syscall rtio_cqe_get_mempool_buffer() com buff/buff_len apontando para memória que ela pode ler, mas não escrever, e com uma entrada de conclusão da fila (completion-queue entry) cujo campo flags está totalmente sob seu controle (apenas RTIO_CQE_FLAG_MEMPOOL_BUFFER em flags[7:0] é necessário; flags[19:8] e flags[31:20] fornecem o índice do bloco e a contagem). O kernel então executa uma gravação de tamanho de ponteiro e outra de 4 bytes através desses endereços enquanto opera em modo supervisor. Para alcançar essa gravação, são necessários CONFIG_USERSPACE junto com CONFIG_RTIO_SYS_MEM_BLOCKS, as configurações por trás do RTIO_DEFINE_WITH_MEMPOOL; sem a última, a implementação retorna -ENOTSUP e não realiza nenhuma escrita.
Dois desfechos podem ocorrer. Se o alvo estiver em uma partição de domínio de memória declarada como K_MEM_PARTITION_P_RW_U_RO (privilegiado leitura-escrita, usuário apenas-leitura), a gravação em modo kernel tem sucesso e deposita valores parcialmente escolhidos pelo atacante na memória que o domínio da memória havia marcado como somente leitura para essa thread, contornando a proteção de escrita do particionamento. Se o alvo estiver em uma memória globalmente legível mas não gravável, como .text/.rodata no flash, a gravação causa um fault (falha) em modo kernel; o fault é entregue a z_fatal_error() e o k_sys_fatal_error_handler() padrão paralisa ou reinicia o dispositivo, proporcionando à thread sem privilégios uma negação de serviço completa e confiável.
A verificação da permissão de leitura limita os danos: o endereço ainda deve ser legível pela thread chamadora, portanto a memória privada do kernel não pode ser alvo e nenhum dado confidencial é revelado. A correção substitui ambas as verificações por K_SYSCALL_MEMORY_WRITE(), assim uma thread sem permissão de escrita é terminada pelo K_OOPS antes que a implementação seja executada; o argumento cqe permanece corretamente validado para leitura.
If you want to get the best quality for vulnerability data then you always have to consider VulDB.