@@ -12,14 +12,32 @@ pub struct Mmap(Vec<u8>);
1212
1313#[ cfg( not( any( miri, target_arch = "wasm32" ) ) ) ]
1414impl Mmap {
15- /// # Safety
16- ///
1715 /// The given file must not be mutated (i.e., not written, not truncated, ...) until the mapping is closed.
1816 ///
19- /// However in practice most callers do not ensure this, so uses of this function are likely unsound.
17+ /// This process must not modify nor remove the backing file while the memory map lives.
18+ /// For the dep-graph and the work product index, it is as soon as the decoding is done.
19+ /// For the query result cache, the memory map is dropped in save_dep_graph before calling
20+ /// save_in and trying to remove the backing file.
21+ ///
22+ /// There is no way to prevent another process from modifying this file.
23+ ///
24+ /// This means in practice all uses of this function are theoretically unsound, but also
25+ /// the way rustc uses `Mmap` (reading bytes, validating them afterwards *anyway* to detect
26+ /// corrupted files) avoids the actual issues this could cause.
27+ ///
28+ /// Someone may truncate our file, but then we'll SIGBUS, which is not great, but at least
29+ /// we won't succeed with corrupted data.
30+ ///
31+ /// To get a bit more hardening out of this we will set the file as readonly before opening it.
2032 #[ inline]
21- pub unsafe fn map ( path : impl AsRef < Path > ) -> io:: Result < Self > {
33+ pub fn map ( path : impl AsRef < Path > ) -> io:: Result < Self > {
34+ let path = path. as_ref ( ) ;
35+ let mut perms = std:: fs:: metadata ( path) ?. permissions ( ) ;
36+ perms. set_readonly ( true ) ;
37+ std:: fs:: set_permissions ( path, perms) ?;
38+
2239 let file = File :: open ( path) ?;
40+
2341 // By default, memmap2 creates shared mappings, implying that we could see updates to the
2442 // file through the mapping. That would violate our precondition; so by requesting a
2543 // map_copy_read_only we do not lose anything.
@@ -34,7 +52,7 @@ impl Mmap {
3452#[ cfg( any( miri, target_arch = "wasm32" ) ) ]
3553impl Mmap {
3654 #[ inline]
37- pub unsafe fn map ( path : impl AsRef < Path > ) -> io:: Result < Self > {
55+ pub fn map ( path : impl AsRef < Path > ) -> io:: Result < Self > {
3856 Ok ( Mmap ( std:: fs:: read ( path) ?) )
3957 }
4058}
0 commit comments