@@ -54,6 +54,8 @@ bitflags::bitflags! {
54
54
const MAY_READ = 1 << 3 ;
55
55
const MAY_WRITE = 1 << 4 ;
56
56
const MAY_EXEC = 1 << 5 ;
57
+
58
+ const SHARED = 1 << 6 ;
57
59
}
58
60
}
59
61
@@ -369,7 +371,6 @@ impl MMapFile {
369
371
370
372
#[ derive( Clone ) ]
371
373
pub struct Mapping {
372
- pub flags : MMapFlags ,
373
374
vm_flags : VmFlag ,
374
375
375
376
pub start_addr : VirtAddr ,
@@ -474,7 +475,7 @@ impl Mapping {
474
475
let addr = addr. align_down ( Size4KiB :: SIZE ) ;
475
476
let size = Size4KiB :: SIZE . min ( file. size as u64 - ( addr - self . start_addr ) ) ;
476
477
477
- return if self . flags . contains ( MMapFlags :: MAP_SHARED ) {
478
+ return if self . vm_flags . contains ( VmFlag :: SHARED ) {
478
479
self . handle_pf_shared_file ( offset_table, reason, addr, offset as _ , size as _ )
479
480
} else {
480
481
self . handle_pf_private_file ( offset_table, reason, addr, offset as _ , size as _ )
@@ -545,7 +546,7 @@ impl Mapping {
545
546
let frame = mmap_file
546
547
. file
547
548
. inode ( )
548
- . mmap ( offset, size, self . flags )
549
+ . mmap ( offset, size, MMapFlags :: empty ( ) )
549
550
. expect ( "handle_pf_file: file does not support mmap" ) ;
550
551
551
552
unsafe {
@@ -764,7 +765,6 @@ impl Mapping {
764
765
} ) ;
765
766
766
767
let new_mapping = Mapping {
767
- flags : self . flags ,
768
768
start_addr : end,
769
769
end_addr : end + ( self . end_addr - end) ,
770
770
file : new_file,
@@ -868,13 +868,10 @@ impl VmProtected {
868
868
return false ;
869
869
}
870
870
871
- let is_private = map. flags . contains ( MMapFlags :: MAP_PRIVATE ) ;
872
- let is_annon = map. flags . contains ( MMapFlags :: MAP_ANONYOMUS ) ;
873
-
874
871
let mut address_space = AddressSpace :: this ( ) ;
875
872
let mut offset_table = address_space. offset_page_table ( ) ;
876
873
877
- match ( is_private , is_annon ) {
874
+ match ( !map . vm_flags . contains ( VmFlag :: SHARED ) , map . file . is_none ( ) ) {
878
875
( true , true ) => {
879
876
map. handle_pf_private_anon ( & mut offset_table, reason, accessed_address)
880
877
}
@@ -970,9 +967,6 @@ impl VmProtected {
970
967
file : Option < DirCacheItem > ,
971
968
vm_flags : VmFlag ,
972
969
) -> Option < VirtAddr > {
973
- // TODO: Check file permissions:
974
- // * Do not allow writing to an {read, append}-only file.
975
-
976
970
let z = file. clone ( ) ;
977
971
978
972
// Offset is required to be a multiple of page size.
@@ -1030,19 +1024,16 @@ impl VmProtected {
1030
1024
// Merge same mappings instead of creating a new one.
1031
1025
if let Some ( prev) = cursor. peek_prev ( ) {
1032
1026
if prev. end_addr == addr
1033
- && prev. flags == flags
1034
- && prev. protection ( ) == ( vm_flags & VM_PROT_MASK )
1027
+ && prev. vm_flags == vm_flags
1035
1028
&& prev. file . is_none ( )
1029
+ && file. is_none ( )
1036
1030
{
1037
1031
prev. end_addr = addr + size_aligned;
1038
-
1039
1032
return addr;
1040
1033
}
1041
1034
}
1042
1035
1043
1036
cursor. insert_before ( Mapping {
1044
- flags,
1045
-
1046
1037
start_addr : addr,
1047
1038
end_addr : addr + size_aligned,
1048
1039
@@ -1077,21 +1068,19 @@ impl VmProtected {
1077
1068
for mmap in & self . mappings {
1078
1069
if let Some ( file) = mmap. file . as_ref ( ) {
1079
1070
log:: debug!(
1080
- "{:?}..{:?} => {:?}, {:?} (offset={:#x}, size={:#x})" ,
1071
+ "{:?}..{:?} => {:?} (offset={:#x}, size={:#x})" ,
1081
1072
mmap. start_addr,
1082
1073
mmap. end_addr,
1083
1074
mmap. vm_flags,
1084
- mmap. flags,
1085
1075
file. offset,
1086
1076
file. size,
1087
1077
) ;
1088
1078
} else {
1089
1079
log:: debug!(
1090
- "{:?}..{:?} => {:?}, {:?} " ,
1080
+ "{:?}..{:?} => {:?}" ,
1091
1081
mmap. start_addr,
1092
1082
mmap. end_addr,
1093
1083
mmap. vm_flags,
1094
- mmap. flags,
1095
1084
) ;
1096
1085
}
1097
1086
}
@@ -1376,7 +1365,7 @@ impl VmProtected {
1376
1365
1377
1366
for map in self . mappings . iter ( ) . filter ( |map| {
1378
1367
// Do not copy page table entries where a page fault can map them correctly.
1379
- !map. flags . contains ( MMapFlags :: MAP_SHARED ) && map. vm_flags . contains ( VmFlag :: MAY_WRITE )
1368
+ !map. vm_flags . contains ( VmFlag :: SHARED ) && map. vm_flags . contains ( VmFlag :: MAY_WRITE )
1380
1369
} ) {
1381
1370
offset_table. copy_page_range ( & mut current, map. start_addr ..=map. end_addr ) ;
1382
1371
}
@@ -1406,18 +1395,31 @@ impl Vm {
1406
1395
offset : usize ,
1407
1396
file : Option < Arc < FileHandle > > ,
1408
1397
) -> Option < VirtAddr > {
1409
- let vm_flags =
1398
+ let mut vm_flags =
1410
1399
VmFlag :: from ( protection) | VmFlag :: MAY_READ | VmFlag :: MAY_WRITE | VmFlag :: MAY_EXEC ;
1411
1400
1412
1401
let map_type = flags & ( MMapFlags :: MAP_SHARED | MMapFlags :: MAP_PRIVATE ) ;
1413
1402
1414
1403
match ( map_type, file. as_ref ( ) ) {
1415
1404
( MMapFlags :: MAP_SHARED , Some ( file) ) => {
1416
- if protection. contains ( MMapProt :: PROT_WRITE ) && !file. is_writable ( ) {
1417
- return None ; // EACCES
1405
+ vm_flags. insert ( VmFlag :: SHARED ) ;
1406
+
1407
+ if !file. is_writable ( ) {
1408
+ if protection. contains ( MMapProt :: PROT_WRITE ) {
1409
+ return None ; // EACCES
1410
+ }
1411
+
1412
+ // The mapping is going to be read-only forever so, it can be converted into a
1413
+ // private mapping.
1414
+ vm_flags. remove ( VmFlag :: MAY_WRITE | VmFlag :: SHARED ) ;
1418
1415
}
1419
1416
1420
- // TODO: check for append-only files.
1417
+ if !file. is_readable ( ) {
1418
+ // return None; // EACCES
1419
+ }
1420
+
1421
+ // TODO: * check if the filsystem is noexec mounted and remove the MAY_EXEC flag.
1422
+ // * error out if prot contains PROT_EXEC & filesystem is noexec.
1421
1423
}
1422
1424
1423
1425
( MMapFlags :: MAP_PRIVATE , Some ( file) ) => {
@@ -1429,6 +1431,7 @@ impl Vm {
1429
1431
// * error out if prot contains PROT_EXEC & filesystem is noexec.
1430
1432
}
1431
1433
1434
+ ( MMapFlags :: MAP_SHARED , None ) => vm_flags. insert ( VmFlag :: SHARED ) ,
1432
1435
_ => { }
1433
1436
}
1434
1437
0 commit comments