@@ -12,14 +12,32 @@ pub struct Mmap(Vec<u8>);
12
12
13
13
#[ cfg( not( any( miri, target_arch = "wasm32" ) ) ) ]
14
14
impl Mmap {
15
- /// # Safety
16
- ///
17
15
/// The given file must not be mutated (i.e., not written, not truncated, ...) until the mapping is closed.
18
16
///
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.
20
32
#[ 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
+
22
39
let file = File :: open ( path) ?;
40
+
23
41
// By default, memmap2 creates shared mappings, implying that we could see updates to the
24
42
// file through the mapping. That would violate our precondition; so by requesting a
25
43
// map_copy_read_only we do not lose anything.
@@ -34,7 +52,7 @@ impl Mmap {
34
52
#[ cfg( any( miri, target_arch = "wasm32" ) ) ]
35
53
impl Mmap {
36
54
#[ inline]
37
- pub unsafe fn map ( path : impl AsRef < Path > ) -> io:: Result < Self > {
55
+ pub fn map ( path : impl AsRef < Path > ) -> io:: Result < Self > {
38
56
Ok ( Mmap ( std:: fs:: read ( path) ?) )
39
57
}
40
58
}
0 commit comments