UIO 드라이버가 커널에 등록되지 않은 경우 파일 설명자(사용자 공간에서)를 닫습니다.

UIO 드라이버가 커널에 등록되지 않은 경우 파일 설명자(사용자 공간에서)를 닫습니다.

Linux를 실행하는 임베디드 시스템에는 UIO의 커널 드라이버를 활용하는 사용자 공간에 PCI 드라이버가 있습니다. 애플리케이션은 __uio_register_device()커널에서 호출된 장치 등록을 트리거할 수 있습니다 uio.c. 그런 다음 응용프로그램은 장치 파일( /dev/uio0)을 엽니다. 그런 다음 장치 정보를 보유하고 있는 일부 커널 메모리를 확보하기 위해 장치 등록을 취소( )함으로써 uio_unregister_device()올바르지 않게 동작합니다 . 그런 다음 응용 프로그램은 파일을 닫고 해제된 포인터에 액세스 중이므로 커널이 패닉 상태가 됩니다.

애플리케이션을 수정하는 것 외에도 어떻게 Linux 커널을 이에 대해 견고하게 만들 수 있습니까?

uio_open()uio_release()키 할당 메모리(in)에 대한 파일 포인터를 가져 옵니다 private_data. 그런데 uio_unregister_device()이런 정보가 없어서 어떻게 해야할지 모르겠습니다. 아니면 앱에서 파일을 강제로 닫는 방법이 있나요? 무슨 일이 일어나고 있는지에 대한 다른 제안이나 다른 설명이 있습니까?

편집: 아래와 같이 쉽게 재현할 수 있으며 사용자 공간 관점을 보여줍니다.

# 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...

충돌의 원인은 Unable to handle kernel paging request at virtual address세 가지 다른 스타일입니다. idev또는 유효하지 않은 포인터(반드시 NULL일 필요는 없으며 임의의 데이터임) idev->info.idev->owner

관련 정보