
CVE-2021-3679 악용 및 해당 수정 사항에 대한 문서
이것은 rb_per_cpu_empty의 로직 버그를 입증하기 위해 트리거하는 개념 증명 프로그램입니다. 이 버그에 걸린 프로그램은 커널 공간의 tracing_read_pipe에서 CPU를 소모하는 무한 루프(데드루프)에 빠져 어떤 UNIX 시그널(SIGKILL 포함)로도 일시 중지하거나 종료할 수 없게 됩니다.
seq_buf_used 계산 버그(리눅스 4.5에서 수정됨)와 유사한(데드루프 및 CPU 소모) 동작을 보이지만, 이 프로그램은 완전히 다른 원인을 가지며 3.10부터 5.14-rc1까지의 커널에 존재할 것으로 추정되는 또 다른 버그의 존재를 입증하기 위한 것입니다(POC 실행 결과 참조).
면책 조항: 이 개념 증명 프로그램은 리눅스를 멈추게 하고 많은 전력을 소모할 수 있으며, 버그가 발생하면 UNIX 시그널로 종료할 수 없습니다. 사용에 따른 책임은 본인에게 있습니다.
이 개념 증명 스크립트를 실행하기 전에 다음 패키지 또는 명령이 설치되어 있어야 합니다.
gcc
realpath
nm
또한 awk 및 grep과 같은 Bash 및 문자열 처리 명령도 필요하며, 대부분의 배포판에 포함되어 있을 것입니다.
bash 스크립트이지만 uprobe를 지정하는 코드 부분은 플랫폼에 따라 다릅니다(uprobe에서는 $argN을 사용할 수 없습니다). 우리는 i386, x86_64, arm, aarch64를 지원합니다. 자신의 플랫폼 지원을 추가하셔도 좋습니다.
개념 증명을 실행하려면 루트 권한으로 다음 명령을 실행하십시오:
./rbdetonate

개념 증명으로 버그가 트리거되면 CPU 코어 하나를 완전히 소모하는 dd 프로세스가 생성되며, 이 프로세스는 SIGKILL과 같은 UNIX 시그널만으로는 종료할 수 없습니다.
rbdetonate 스크립트의 bash 프로세스는 종료될 수 있지만, SIGINT 시그널을 보내면 bash 구현에 따라 종료될 수도 있고 아닐 수도 있습니다. 그리고 최신 버전의 bash는 생성된 dd 프로세스가 실행 중일 때만 SIGINT로 종료할 수 있습니다.

rbdetonate는 여러 번 재시도한 후에도 dd 프로세스를 만들 수 없으면 종료되고 Nothing buggy has been detected를 출력할 수 있습니다. 다만 8192번을 재시도하기 때문에 시간이 다소 걸릴 수 있습니다.
설명: 이 버그는 이론상 사용자 공간 추적 기능(>=3.10)이 있는 모든 버전에 존재하지만, 오래된 커널 버전에서는 uprobe가 여러 면에서 제대로 작동하지 않았습니다. 이 동작을 수정하는 데 도움을 주시면 감사하겠습니다.
A: 루트 권한으로 다음 명령을 실행하기만 하면 프로그램이 데드루프에서 빠져나옵니다.
echo > /sys/kernel/debug/tracing/instances/rbdetonate/trace
A: 아니요. 여기서 사용된 빌드 도구는 단지 우리가 설계한 절차에 따라 CPU#0의 링 버퍼 페이지에 쓰기만 하여 결정적(deterministic) 결과를 생성하는 rbwrite 프로그램을 빌드하기 위한 것입니다.
이 개념 증명의 경우 간단히 rbwrite 프로그램의 컴파일된 버전(위 코드와 유사한)도 사용할 수 있으며, 그 후에 트레이스포인트의 주소를 얻을 수 있습니다.
리눅스 추적을 사용하는 경우, 애플리케이션이 만드는 노이즈를 신경 쓰지 않는다면 syscall과 커널 함수에 kprobe 트레이스포인트를 추가해도 이벤트가 생성됩니다. 그러나 개념 증명의 경우 이는 비결정성을 도입할 수 있으므로 선호되지 않습니다.
| 버전 | 재현 | 스크린샷 |
|---|
| 5.14.0-rc2-00479-g86020194bc7e (수정 버전) | N | 5.14.0-rc2-00479-g86020194bc7e.png |
| 5.14.0-rc2-00478-g2734d6c1b1a0 (5.14.0-rc2) | Y | 5.14.0-rc2-00478-g2734d6c1b1a0.png |
| 5.4.0-77-generic | Y | 5.4.0-77-generic.png |
| 4.4.0-142-generic | Y | 4.4.0-142-generic.png |