Rust 보로우 체커에서 11년 된 건전성 버그 발견, 구조체 라이프타임 제약 우회 가능
- 구조체 라이프타임 제약이 공변성(covariance) 필드 대입으로 우회되는 건전성 버그가 Rust 이슈 #164250으로 등록됨
- 재현 코드는 Drop 구현 안에서 참조를 저장해서 스택 변수 수명이 끝난 뒤에도 값이 살아남게 만듦, 컴파일은 되고 asan에서는 stack-use-after-scope 오류가 발생함
- 버그는 nightly와 1.85.0 이상 stable에서 모두 재현됨
- 메인테이너 lcnr은 악용하려면 의도적으로 악의적인 Drop 구현이 필요하다고 설명하고, 11년 동안 드러나지 않은 점을 근거로 듦
- 이슈는 I-unsound와 P-high 라벨을 달고 타입 팀이 검토 중이며, 새 trait solver가 이런 건전성 문제 일부를 해결할 것으로 언급됨
Hacker News opinions
진짜 최소 예제가 너무 단순해서 놀랐음. 일반 코드에서 충분히 마주칠 법한 모양이라 더 찜찜함.
근데 11년 동안 안 걸렸다는 건 실제로 이렇게 쓰는 사람이 거의 없었다는 뜻 아님? 나는 Rust 시스템 쪽에서 4년 일했는데 커스텀 Drop 구현 쓸 일이 한 번도 없었음. 진짜 함정은 그 부분인 듯.
loop {}도 한때 UB였음. l-unsound 중에 황당한 것도 있지만 몇 개는 그냥 그럴 만한 것들임. 진짜 많이 쓰는 코드였으면 10년씩 묻혀 있진 않았겠지.
오래된 소프트웨어가 새 거보다 믿을 만한 이유가 이거임. 버그는 많이 써보면서 발견되는 거니까.
Rust는 variance를 손으로 아예 못 쓰게 되어 있어서 이런 버그가 방치되기 쉬움. 엄격하게 만들어야 할 때만 조심하면 되는데 그 경우도 드묾임.
인증 받은 안전 필수용 컴파일러 Ferrocene도 같은 코드 쓰니까 같은 문제 있을 듯. 근데 implied bounds 쓰지 말라는 가이드가 있을 수도 있음.
타입 시스템 버그 찾을 때 제일 먼저 보는 게 가변성이랑 다른 기능 조합임. 이 예제도 가변성 없이 재현되는지 궁금하더라.
AI로 컴파일러 버그 찾다 보면 완벽에 가까워진다는 말은 좀 과한 것 같음. 기능 추가할 때마다 트레이드오프가 계속 생겨서 완전한 신뢰성은 안 나올 듯.
컴파일된 바이너리에 이 취약점이 있는지 알 방법이 없는 게 문제임. VM이랑 달리 런타임만 갈아끼울 수 없으니 다 다시 빌드해야 함.
요즘은 어셈블리나 기계어 레벨에서 스캔하는 도구도 있음. 안 하는 사람이 많을 뿐이지.