Feche o descritor de arquivo (no espaço do usuário) quando o driver UIO não estiver registrado (no kernel)

2

Em um sistema embarcado rodando Linux, temos um driver PCI no espaço do usuário fazendo uso do driver do kernel para o UIO. O aplicativo pode acionar o registro do dispositivo que chama __uio_register_device() no uio.c do kernel. Em seguida, o aplicativo abre o arquivo do dispositivo ( /dev/uio0 ). E então ele se comporta mal ao cancelar o registro do dispositivo ( uio_unregister_device() ), o que libera algumas informações do dispositivo de armazenamento de memória do kernel. Em seguida, o aplicativo fecha o arquivo - e o kernel entra em pane porque os ponteiros que foram liberados estão sendo acessados.

Além de consertar o aplicativo, como posso tornar o kernel do Linux robusto contra isso?

uio_open() e uio_release() obtêm ponteiros de arquivos que apontam para a memória alocada crítica (em private_data ). Mas uio_unregister_device() não tem essa informação, então não sei o que fazer. Ou há uma maneira de forçar o fechamento do arquivo no aplicativo? Alguma outra sugestão ou uma interpretação diferente do que está acontecendo?

Editar: pode ser facilmente reproduzido da seguinte forma - e mostra a perspectiva do espaço do usuário:

# replace '1234 abcd' by vendor id and device id
echo '1234 abcd' > /sys/bus/pci/drivers/uio_pci_generic/new_id
echo '0000:00:01.0' > /sys/bus/pci/drivers/uio_pci_generic/bind
# 'bind' may not even be needed. /dev/uio0 is created
cat /dev/uio0 &
# now be bad
echo '0000:00:01.0' > /sys/bus/pci/drivers/uio_pci_generic/unbind
kill <cat process ID>
# kernel panic...

Provoca uma falha devido a Unable to handle kernel paging request at virtual address - com três diferentes sabores. O idev , idev->info ou idev->owner é um ponteiro inválido (não é necessário NULL, apenas dados aleatórios).

    
por Hans W. Heckel 15.11.2017 / 16:57

0 respostas