Rust 빌림 검사기에서 11년 된 건전성 버그들 발견

1 week ago 14

공변적 필드 대입으로 구조체의 수명 제약을 우회하는 재현 코드가 발견됨. 컴파일이 거부돼야 할 코드가 통과하고, Drop에서 짧은 수명의 참조를 'static 참조로 취급할 수 있음 최초 재현 코드는 수명이 끝난 지역 변수의 참조를 전역 저장소에서 다시 사용하며, AddressSanitizer 실행 시 stack-use-after-scope 오류로 종료됨 최초 보고는 당시 nightly와 최소 Rust 1.85.0까지의 stable에서 문제를 확인했으며, 후속 재현에서는 1.4부터 건전성 문제가 있었음을 확인함 재현 범위는 'static 제약에만 국한되지 않음. 수명 간 관계를 이용하거나 소멸자에서 클로저를 호출하는 코드에서도 해제된 메모리 접근을 재현함 후속 논의에서는 타입 단일화(unification) 자체가 수명 제약을 검사하지 않을 가능성까지 제기됨. 우선순위는 P-high로 정해졌으며, 제공된 논의에는 수정안이나 해결 결과가 없음 필드 대입으로 우회되는 수명 제약 이슈 #164250은 공변적 필드 대입으로 구조체의 수명 요구사항을 우회하는 문제를 다룸 최초 재현은 struct Q<T: 'static + Send>(Option<T>)를 정의하고, Q(None)으로 생성한 뒤 지역 String의 참조를 q.0 = Some(&l) 로 대입함 Drop 구현은 self.0.take()로 값을 꺼내 전역 KEPT에 저장함 KEPT의 타입은 Mutex<Vec<Box<dyn std::any::Any + Send>>>이며, 이후 downcast_ref::<&'static String>()으로 참조를 꺼내 출력함 기대 동작은 컴파일 거부지만, 실제로는 컴파일된 뒤 원래 문자열 대신 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX을 출력함 지역 변수의 스코프가 끝난 뒤 같은 문자열을 가진 새 String을 생성하는 재현 코드임 AddressSanitizer를 사용하면 AddressSanitizer: stack-use-after-scope 오류로 종료됨 재현 링크: AddressSanitizer 사용, AddressSanitizer 미사용 축약된 재현에는 Send나 전역 저장소가 필요하지 않음. Q<T: 'static>(Option<T>) 와 Drop만으로, 소멸자 내부가 'static이 아닌 &String...

Read Entire Article




피플앤툴즈 네트워크
🛍 샵