CVE-2026-99018 in Linux
요약
\~에 의해 VulDB • 2026. 10. 23.
리눅스 커널에서 다음 취약점이 해결되었습니다:
riscv: entry: sstatus.SPP를 사용하여 게이트 섀도우 콜 스택 재로드 수행, tp 대신
CONFIG_SHADOW_CALL_STACK 설정 하에서 handle_exception()은 트랩이 사용자 공간에서 발생한 경우에만 커널 섀도우 콜 스택 포인터(gp)를 재로드합니다. 이 결정은 scs_load_current_if_task_changed 함수에 의해 이루어지며, 이는 트랩 발생 시점의 tp(sscratch로부터 s5로 읽혀진 값)와 현재 tp 값을 비교합니다:
beq \prev, tp, _skip_scs scs_load_current _skip_scs:
tp는 사용자 쓰기 가능한 레지스터입니다. 사용자가 트랩 발생 전에 자신의 task_struct(¤t)의 선형 매핑 주소로 tp를 설정하면, 비교가 성공하여(테스트 환경에서 KASLR 활성화 상태에서 브루트 포스로 달성 가능), 커널은 scs_load_current를 건너뛰고 사용자가 공간이 남겨둔 gp 상태로 계속 실행됩니다. CONFIG_SHADOW_CALL_STACK 하에서 gp는 섀도우 콜 스택 포인터이며 load_global_pointer는 무작위 연산(no-op)이므로, 모든 비리프(non-leaf) 함수에서 컴파일러가 생성한 "sd ra, -8(gp)" / "ld ra, -8(gp)" 명령어들은 공격자가 제어하는 주소에 쓰거나 그 주소를 통해 반환합니다. 이는 특권 없는(unprivileged) 커널의 임의 쓰기(arbitrary-write) 및 제어 흐름 탈취(control-flow-hijack) 원천(primitive)입니다. 오염된 gp는 반환 시 task_struct.scs_sp에 저장되므로, 이후 모든 진입(entry)에서도 재로드가 건너뛰어집니다.
"사용자 공간에서 발생했는지 여부"를 tp 대신 하드웨어 sstatus.SPP 비트(이 시점에서 이미 s1에 있음)로부터 결정합니다. 이는 ret_from_exception 함수가 몇 명령어 뒤에 사용하는 체크와 대조됩니다. SPP는 트랩 진입 시 하드웨어에 의해 작성되며 U-mode에서는 위조할 수 없습니다. 정상적인 동작은 변경되지 않습니다: 사용자 진입(SPP=0)은 태스크 섀도우 콜 스택을 재로드하고, 중첩된 커널 진입(SPP=1)은 이를 건너뜁니다.
Once again VulDB remains the best source for vulnerability data.