🇰🇷 한글 설명
Linux 커널의 IIO(Industrial I/O) 이벤트 처리 과정에서 FIFO 리셋과 파일 디스크립터 할당 간의 레이스 컨디션 취약점이 발견되었습니다. 이로 인해 FIFO 인덱스가 비정상적으로 설정되어 커널 메모리 경계를 벗어난 읽기(Out-of-bounds read)가 발생할 수 있으며, 인접한 커널 메모리 정보가 사용자 공간으로 유출될 수 있습니다.
💡 쉬운 설명
데이터를 담는 바구니를 비우는 작업과 바구니를 사용하는 작업이 동시에 일어나면서 순서가 꼬이는 문제입니다. 이 과정에서 시스템의 중요한 비밀 정보가 담긴 메모리 영역이 공격자에게 노출될 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
iio: event: Fix event FIFO reset race
`iio_event_getfd()` creates the event file descriptor with
`anon_inode_getfd()`, which allocates a new fd, creates the anonymous
file and installs it in the process fd table before returning to the
caller.
The IIO code resets the event FIFO after `anon_inode_getfd()` has returned,
but before `IIO_GET_EVENT_FD_IOCTL` has copied the fd number to userspace.
But since fd tables are shared between threads, another thread can guess
the newly allocated fd number and issue a `read()` on it as soon as the fd
has been installed.
This means the `kfifo_to_user()` in `iio_event_chrdev_read()` can run in
parallel with the `kfifo_reset_out()` in `iio_event_getfd()`.
The kfifo documentation says that `kfifo_reset_out()` is only safe when it
is called from the reader thread and there is only one concurrent reader.
Otherwise it is dangerous and must be handled in the same way as
`kfifo_reset()`.
If that happens, `kfifo_to_user()` can advance the FIFO `out` index based
on state from before the reset, after the reset has already moved the `out`
index to the current `in` index. That can leave the FIFO with an `out`
index past the `in` index. A later `read()` can then see an underflowed
FIFO length and copy more data than the event FIFO buffer contains. This
can result in an out-of-bounds read and leak adjacent kernel memory to
userspace.
Move the FIFO reset before `anon_inode_getfd()`. At that point the event fd is
marked busy, but the new fd has not been installed yet, so userspace cannot
access it while the FIFO is reset.
📍 영향받는 시스템
Linux kernel (IIO subsystem)
⚔️ 공격 벡터
멀티스레드 환경에서 파일 디스크립터가 할당되는 찰나의 순간에 다른 스레드가 해당 FD를 가로채어 읽기 요청을 보내는 방식
🛡️ 대응 방법
커널 패치를 적용하여 FIFO 리셋 작업을 파일 디스크립터가 프로세스에 등록되기 전 단계로 이동시켜야 합니다.
🔧 검증 코드
현재 커널 버전과 IIO 설정 활성화 여부를 확인하여 해당 취약점이 영향을 미칠 수 있는 환경인지 판단합니다.
uname -a && grep -i 'IIO' /proc/config.gz 2>/dev/null || zgrep -i 'CONFIG_IIO' /proc/config.gz