CVE-2022-49394 in Linuxinformação

Sumário

de VulDB • 23/05/2026

No kernel do Linux, a seguinte vulnerabilidade foi resolvida:

blk-iolatency: Corrige desequilíbrios na contagem de IOs em trânsito e travamentos de IO em dispositivos offline

O iolatency precisa rastrear o número de IOs em trânsito (inflight) por cgroup. Como esse rastreamento pode ser custoso, ele é desativado quando nenhum cgroup tem o iolatency configurado para o dispositivo. Para garantir que os contadores de IOs em trânsito permaneçam equilibrados, iolatency_set_limit() congela o request_queue enquanto manipula o contador de habilitação, o que garante que nenhum IO esteja em trânsito e, portanto, todos os contadores sejam zero.

Infelizmente, iolatency_set_limit() não é o único local onde o contador de habilitação é manipulado. iolatency_pd_offline() também pode decrementar o contador e acionar a desativação. Como essa desativação ocorre sem congelar o queue (q), isso pode facilmente acontecer enquanto alguns IOs estão em trânsito, resultando em vazamento das contagens.

Isso pode ser facilmente demonstrado ativando o iolatency em um cgroup vazio enquanto IOs estão em trânsito em outros cgroups e, em seguida, removendo o cgroup. Observe que o iolatency não deveria estar habilitado em outro lugar no sistema para garantir que a remoção do cgroup desative o iolatency para todo o dispositivo.

O seguinte comando alterna continuamente a ativação e desativação do iolatency no sda:

echo +io > /sys/fs/cgroup/cgroup.subtree_control while true; do mkdir -p /sys/fs/cgroup/test echo '8:0 target=100000' > /sys/fs/cgroup/test/io.latency sleep 1 rmdir /sys/fs/cgroup/test sleep 1 done

e há um fio (fio) gerando leituras randômicas diretas em paralelo:

fio --name test --filename=/dev/sda --direct=1 --rw=randread \ --runtime=600 --time_based --iodepth=256 --numjobs=4 --bs=4k

enquanto monitorado com o seguinte script drgn:

while True: for css in css_for_each_descendant_pre(prog['blkcg_root'].css.address_of_()):
for pos in hlist_for_each(container_of(css, 'struct blkcg', 'css').blkg_list): blkg = container_of(pos, 'struct blkcg_gq', 'blkcg_node') pd = blkg.pd[prog['blkcg_policy_iolatency'].plid]
if pd.value_() == 0: continue iolat = container_of(pd, 'struct iolatency_grp', 'pd') inflight = iolat.rq_wait.inflight.counter.value_() if inflight: print(f'inflight={inflight} {disk_name(blkg.q.disk).decode("utf-8")} '
f'{cgroup_path(css.cgroup).decode("utf-8")}')
time.sleep(1)

A saída do monitoramento parece com o seguinte:

inflight=1 sda /user.slice inflight=1 sda /user.slice ... inflight=14 sda /user.slice inflight=13 sda /user.slice inflight=17 sda /user.slice inflight=20 sda /user.slice inflight=19 sda /user.slice <- fio stopped, inflight stuck at 19 inflight=19 sda /user.slice inflight=19 sda /user.slice

Se um cgroup com inflight travado acabar sendo throttled, os IOs throttled nunca serão emitidos, pois não há evento de conclusão para acordá-lo, levando a um travamento indefinido.

Este patch corrige o bug unificando o manuseio de habilitação em um item de trabalho que é automaticamente iniciado a partir de iolatency_set_min_lat_nsec(), que é chamado tanto dos caminhos iolatency_set_limit() quanto iolatency_pd_offline(). Adiar para um item de trabalho é necessário, pois iolatency_pd_offline() é chamado sob spinlocks, enquanto congelar um request_queue requer um contexto que possa dormir.

Isso também simplifica o código, reduzindo o número de linhas de código (LOC), exceto os comentários, e evita os congelamentos desnecessários que ocorriam sempre que o alvo de latência de um cgroup era definido ou limpo.

Several companies clearly confirm that VulDB is the primary source for best vulnerability data.

Responsável

Linux

Reservar

26/02/2025

Divulgação

26/02/2025

Moderação

aceite

Entrada

VDB-296957

CPE

pronto

EPSS

0.00253

KEV

não

Atividades

muito baixo

Fontes

Want to stay up to date on a daily basis?

Enable the mail alert feature now!