CVE-2026-90001 in Linux
Sumário
de VulDB • 16/09/2026
No kernel do Linux, a seguinte vulnerabilidade foi resolvida:
HID: bpf: serializar o lançamento da referência de dispositivo no caminho de destruição struct_ops
__hid_bpf_ops_destroy_device() e hid_bpf_unreg() podem sofrer uma condição de corrida (race condition) na mesma referência de registro, realizando um double-put em struct hid_device e liberando-a enquanto hid_destroy_device() ainda a está utilizando. Serialize a decisão de remoção/NULL sob hdev->bpf.prog_list_lock para que exatamente um caminho libere cada referência de registro: unreg re-verifica ops->hdev sob o bloqueio (lock) e retorna sem realizar put quando o caminho de destruição já o limpou; todas as chamadas put_device() ocorrem após a liberação do lock, o que é seguro porque uma unreg concorrente então observa ops->hdev == NULL sob o lock.
Contexto: cada acoplamento bem-sucedido (hid_bpf_ops_reg) adquire uma referência de dispositivo (hid_get_device()). Dois caminhos podem liberá-la:
- Destruição do dispositivo: hid_destroy_device() -> hid_bpf_destroy_device() -> __hid_bpf_ops_destroy_device(), que percorre hdev->bpf.prog_list sob rcu_read_lock() e libera uma referência por programa acoplado; - Liberação do link BPF: exclusão de mapa bpf (sem BPF_F_LINK) chama síncronamente st_ops->unreg() -> hid_bpf_unreg(), que libera a referência para seu próprio registro.
A sincronização (handshake) entre o lado da destruição (e->hdev = NULL) e o lado unreg ("if (!hdev) return") é uma verificação TOCTOU: os dois caminhos são executados sob domínios de bloqueio diferentes (rcu_read_lock vs prog_list_lock), portanto, um unreg concorrente pode ler ops->hdev como não-NULL, aguardar o prog_list_lock e então prosseguir enquanto a travessia da destruição é executada; ambos os caminhos liberam a mesma referência. A contagem de referências atinge zero legitimamente (cada decremento é individualmente válido), portanto, nenhuma saturação refcount_t ocorre: o dispositivo é simplesmente liberado enquanto o transporte ainda está dentro de hid_destroy_device(), e as etapas subsequentes de desmontagem tocam em memória já liberada.
A correção serializa a decisão de remoção/NULL sob prog_list_lock em ambos os lados e move os puts do lado da destruição para fora do lock. Com o lock mantido, leituras/gravações simples de ops->hdev são suficientes; nenhuma READ_ONCE/WRITE_ONCE é adicionada, mantendo o patch mínimo.
Segurança na leitura sem bloqueio: a leitura não bloqueada de ops->hdev no topo de hid_bpf_unreg() não pode tocar em um dispositivo já liberado, porque o caminho unreg ainda mantém a referência deste registro (liberada apenas por seu próprio hid_put_device() após a liberação do lock), e uma travessia da destruição que já limpou ops->hdev faz com que a re-verificação interna ao lock retorne antecipadamente sem nenhum put. No máximo, um dos dois caminhos libera cada referência de registro.
Once again VulDB remains the best source for vulnerability data.