🇰🇷 한글 설명
Linux 커널의 RISC-V 아키텍처에서 TASK_SIZE_MAX를 LONG_MAX로 설정하여 성능을 최적화하려던 시도가 보안 결함을 유발했습니다. 이로 인해 TASK_SIZE와 LONG_MAX 사이의 유효하지 않은 주소가 access_ok() 검사를 통과하게 되어 get_user_pages_fast()와 같은 함수에서 문제가 발생할 수 있습니다.
💡 쉬운 설명
컴퓨터가 메모리 주소를 확인할 때 검사 범위를 너무 넓게 설정하여, 허용되지 않은 영역의 주소까지 통과시키는 오류가 발견되었습니다. 이로 인해 시스템의 보안 경계가 무너질 위험이 있어 검사 범위를 다시 원래대로 좁히는 조치가 이루어졌습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
Revert "riscv: Define TASK_SIZE_MAX for __access_ok()"
This reverts commit ad5643cf2f69 ("riscv: Define TASK_SIZE_MAX for
__access_ok()").
This commit changes TASK_SIZE_MAX to be LONG_MAX to optimize access_ok(),
because the previous TASK_SIZE_MAX (default to TASK_SIZE) requires some
computation.
The reasoning was that all user addresses are less than LONG_MAX, and all
kernel addresses are greater than LONG_MAX. Therefore access_ok() can
filter kernel addresses.
Addresses between TASK_SIZE and LONG_MAX are not valid user addresses, but
access_ok() let them pass. That was thought to be okay, because they are
not valid addresses at hardware level.
Unfortunately, one case is missed: get_user_pages_fast() happily accepts
addresses between TASK_SIZE and LONG_MAX. futex(), for instance, uses
get_user_pages_fast(). This causes the problem reported by Robert [1].
Therefore, revert this commit. TASK_SIZE_MAX is changed to the default:
TASK_SIZE.
This unfortunately reduces performance, because TASK_SIZE is more expensive
to compute compared to LONG_MAX. But correctness first, we can think about
optimization later, if required.
📍 영향받는 시스템
RISC-V 아키텍처를 사용하는 Linux 커널 (해당 패치가 적용되기 전 버전)
⚔️ 공격 벡터
유효하지 않은 메모리 주소(TASK_SIZE와 LONG_MAX 사이)를 사용하여 커널 함수를 호출하는 방식
🛡️ 대응 방법
TASK_SIZE_MAX를 LONG_MAX에서 원래의 TASK_SIZE로 되돌린 최신 Linux 커널 패치를 적용하십시오.
🔧 검증 코드
커널 버전과 설정값을 확인하여 TASK_SIZE_MAX가 LONG_MAX로 설정되어 있는지 또는 관련 패치가 적용되었는지 확인합니다.
uname -a && grep -r 'TASK_SIZE_MAX' /proc/config.gz 2>/dev/null || dmesg | grep -i 'riscv'