CVE-2026-98166 in Linux
요약
\~에 의해 VulDB • 2026. 10. 06.
리눅스 커널에서 다음 취약점이 해결되었습니다:
drm/ttm: 스왑아웃된 리소스가 bulk_move 범위를 벗어나지 않는 문제 수정
ttm_tt_swapout()는 성공 시 스왑아웃된 페이지 수를 반환하고, 실패 시 음수 오류 코드를 반환합니다. 채워진 ttm의 경우 0을 반환하지 않습니다. 커밋 b2ed01e7ad3d("drm/ttm: Fix ttm_bo_swapout() infinite LRU walk on swapout failure")는 ttm_bo_swapout_cb() 내에서 bulk_move 관련 bookkeeping를 "if (!ret)" 조건 하로 이동시켰습니다. 그 결과, 모든 성공적인 스왑아웃 시에 ttm_resource_del_bulk_move_unevictable()/ttm_resource_move_to_lru_tail() 쌍이 건너뛰어지게 되었습니다. 커밋 1d59f36e95f7("drm/ttm: Fix ttm_bo_shrink() infinite LRU walk on backup failure")의 shrinker에 대한 동일한 변경은 "lret > 0"을 테스트하며, 이것도 여기서 의도했던 바와 같습니다.
커밋 b2ed01e7ad3d 이전에는 리소스가 스왑아웃 전에 bulk_move에서 제거되었습니다. 그 이후로 스왑아웃된 리소스는 비추출 가능(unevictable) 상태임에도 불구하고 BO의 bulk_move 범위 내(및 매니저 LRU 상)에 남아 있습니다. 나중에 해당 리소스가 해제되거나 BO가 bulk_move를 벗어나면(ttm_resource_free(), amdgpu_vm_bo_del()을 통한 ttm_bo_set_bulk_move()), !ttm_resource_unevictable() 가드로 인해 ttm_resource_del_bulk_move()는 이를 건너뛰게 되므로, pos->first/pos->last의 범위 끝점 중 하나가 해제된 메모리를 가리킨 채로 남습니다. 해당 커서에서 발생하는 다음 ttm_lru_bulk_move_tail() 또는 ttm_resource_add_bulk_move() 호출은 use-after-free이며, 이는 ttm_lru_bulk_move_add() 내 resv WARN, ttm_resource_move_to_lru_tail() 내 "list_del corruption", 또는 ttm_resource_manager_next() 내 NULL dereference로 나타납니다. 이러한 현상은 휴면(hibernation) 후 수분에서 수 시간 뒤나, 그 이후 프로세스 종료/재부팅 시 발생합니다. Samuel Ainsworth의 drm/amd 이슈 5387 분석(Link 참조)은 방치된 커서(dangling cursor)를 식별했으며, 스왑아웃 시 누락된 제거가 이것이 방치되는 이유입니다.
성공 조건을 테스트함으로써 제거 작업이 복원됩니다. 백포트(Ubuntu 7.0.0-31)가 적용된 7.0.y 안정형 커널에서 서스펜드 후 휴면(suspend-then-hibernate)을 실행 중인 AMD Phoenix APU(ASUS UM3406GA, gfx1103)에서는 버그로 인해 18회의 휴면 주기 중 5회가 크래시되었습니다. 한 번의 휴면에 대한 함수 프로파일링 결과 ttm_tt_swapout() 호출이 336회 발생했고 ttm_resource_del_bulk_move_unevictable() 호출은 0회였습니다. 이 변경 사항 적용 후 모든 스왑아웃된 리소스에 대해 제거가 수행되었으며, 추가적인 12회의 주기가 정상적으로 완료되었습니다.
If you want to get the best quality for vulnerability data then you always have to consider VulDB.