@@ -4,7 +4,7 @@ use std::convert::{TryFrom, TryInto};
4
4
use std:: fs:: {
5
5
read_dir, remove_dir, remove_file, rename, DirBuilder , File , FileType , OpenOptions , ReadDir ,
6
6
} ;
7
- use std:: io:: { self , Read , Seek , SeekFrom , Write } ;
7
+ use std:: io:: { self , ErrorKind , Read , Seek , SeekFrom , Write } ;
8
8
use std:: path:: Path ;
9
9
use std:: time:: SystemTime ;
10
10
@@ -504,7 +504,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
504
504
) -> InterpResult < ' tcx , i32 > {
505
505
let this = self . eval_context_mut ( ) ;
506
506
507
- this. check_no_isolation ( "`open`" ) ?;
507
+ // Reject if isolation is enabled.
508
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
509
+ this. reject_in_isolation ( "`open`" , reject_with) ?;
510
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
511
+ return Ok ( -1 ) ;
512
+ }
508
513
509
514
let flag = this. read_scalar ( flag_op) ?. to_i32 ( ) ?;
510
515
@@ -594,7 +599,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
594
599
fn fcntl ( & mut self , args : & [ OpTy < ' tcx , Tag > ] ) -> InterpResult < ' tcx , i32 > {
595
600
let this = self . eval_context_mut ( ) ;
596
601
597
- this. check_no_isolation ( "`fcntl`" ) ?;
602
+ // Reject if isolation is enabled.
603
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
604
+ this. reject_in_isolation ( "`fcntl`" , reject_with) ?;
605
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
606
+ return Ok ( -1 ) ;
607
+ }
598
608
599
609
if args. len ( ) < 2 {
600
610
throw_ub_format ! (
@@ -785,7 +795,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
785
795
fn unlink ( & mut self , path_op : & OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
786
796
let this = self . eval_context_mut ( ) ;
787
797
788
- this. check_no_isolation ( "`unlink`" ) ?;
798
+ // Reject if isolation is enabled.
799
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
800
+ this. reject_in_isolation ( "`unlink`" , reject_with) ?;
801
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
802
+ return Ok ( -1 ) ;
803
+ }
789
804
790
805
let path = this. read_path_from_c_str ( this. read_scalar ( path_op) ?. check_init ( ) ?) ?;
791
806
@@ -811,7 +826,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
811
826
812
827
let this = self . eval_context_mut ( ) ;
813
828
814
- this. check_no_isolation ( "`symlink`" ) ?;
829
+ // Reject if isolation is enabled.
830
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
831
+ this. reject_in_isolation ( "`symlink`" , reject_with) ?;
832
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
833
+ return Ok ( -1 ) ;
834
+ }
815
835
816
836
let target = this. read_path_from_c_str ( this. read_scalar ( target_op) ?. check_init ( ) ?) ?;
817
837
let linkpath = this. read_path_from_c_str ( this. read_scalar ( linkpath_op) ?. check_init ( ) ?) ?;
@@ -827,7 +847,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
827
847
) -> InterpResult < ' tcx , i32 > {
828
848
let this = self . eval_context_mut ( ) ;
829
849
this. assert_target_os ( "macos" , "stat" ) ;
830
- this. check_no_isolation ( "`stat`" ) ?;
850
+
851
+ // Reject if isolation is enabled.
852
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
853
+ this. reject_in_isolation ( "`stat`" , reject_with) ?;
854
+ // macos stat never sets "EPERM". Set error code "ENOENT".
855
+ this. set_last_error_from_io_error ( ErrorKind :: NotFound ) ?;
856
+ return Ok ( -1 ) ;
857
+ }
858
+
831
859
// `stat` always follows symlinks.
832
860
this. macos_stat_or_lstat ( true , path_op, buf_op)
833
861
}
@@ -840,7 +868,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
840
868
) -> InterpResult < ' tcx , i32 > {
841
869
let this = self . eval_context_mut ( ) ;
842
870
this. assert_target_os ( "macos" , "lstat" ) ;
843
- this. check_no_isolation ( "`lstat`" ) ?;
871
+
872
+ // Reject if isolation is enabled.
873
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
874
+ this. reject_in_isolation ( "`lstat`" , reject_with) ?;
875
+ // macos lstat never sets "EPERM". Set error code "ENOENT".
876
+ this. set_last_error_from_io_error ( ErrorKind :: NotFound ) ?;
877
+ return Ok ( -1 ) ;
878
+ }
879
+
844
880
this. macos_stat_or_lstat ( false , path_op, buf_op)
845
881
}
846
882
@@ -852,7 +888,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
852
888
let this = self . eval_context_mut ( ) ;
853
889
854
890
this. assert_target_os ( "macos" , "fstat" ) ;
855
- this. check_no_isolation ( "`fstat`" ) ?;
891
+
892
+ // Reject if isolation is enabled.
893
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
894
+ this. reject_in_isolation ( "`fstat`" , reject_with) ?;
895
+ // Set error code as "EBADF" (bad fd)
896
+ return this. handle_not_found ( ) ;
897
+ }
856
898
857
899
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
858
900
@@ -874,7 +916,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
874
916
let this = self . eval_context_mut ( ) ;
875
917
876
918
this. assert_target_os ( "linux" , "statx" ) ;
877
- this. check_no_isolation ( "`statx`" ) ?;
919
+
920
+ // Reject if isolation is enabled.
921
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
922
+ this. reject_in_isolation ( "`statx`" , reject_with) ?;
923
+ // statx never sets "EPERM". Set error code "ENOENT".
924
+ this. set_last_error_from_io_error ( ErrorKind :: NotFound ) ?;
925
+ return Ok ( -1 ) ;
926
+ }
878
927
879
928
let statxbuf_scalar = this. read_scalar ( statxbuf_op) ?. check_init ( ) ?;
880
929
let pathname_scalar = this. read_scalar ( pathname_op) ?. check_init ( ) ?;
@@ -1034,7 +1083,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1034
1083
) -> InterpResult < ' tcx , i32 > {
1035
1084
let this = self . eval_context_mut ( ) ;
1036
1085
1037
- this. check_no_isolation ( "`rename`" ) ?;
1086
+ // Reject if isolation is enabled.
1087
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1088
+ this. reject_in_isolation ( "`rename`" , reject_with) ?;
1089
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
1090
+ return Ok ( -1 ) ;
1091
+ }
1038
1092
1039
1093
let oldpath_scalar = this. read_scalar ( oldpath_op) ?. check_init ( ) ?;
1040
1094
let newpath_scalar = this. read_scalar ( newpath_op) ?. check_init ( ) ?;
@@ -1060,7 +1114,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1060
1114
) -> InterpResult < ' tcx , i32 > {
1061
1115
let this = self . eval_context_mut ( ) ;
1062
1116
1063
- this. check_no_isolation ( "`mkdir`" ) ?;
1117
+ // Reject if isolation is enabled.
1118
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1119
+ this. reject_in_isolation ( "`mkdir`" , reject_with) ?;
1120
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
1121
+ return Ok ( -1 ) ;
1122
+ }
1064
1123
1065
1124
#[ cfg_attr( not( unix) , allow( unused_variables) ) ]
1066
1125
let mode = if this. tcx . sess . target . os == "macos" {
@@ -1090,7 +1149,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1090
1149
fn rmdir ( & mut self , path_op : & OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
1091
1150
let this = self . eval_context_mut ( ) ;
1092
1151
1093
- this. check_no_isolation ( "`rmdir`" ) ?;
1152
+ // Reject if isolation is enabled.
1153
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1154
+ this. reject_in_isolation ( "`rmdir`" , reject_with) ?;
1155
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
1156
+ return Ok ( -1 ) ;
1157
+ }
1094
1158
1095
1159
let path = this. read_path_from_c_str ( this. read_scalar ( path_op) ?. check_init ( ) ?) ?;
1096
1160
@@ -1102,7 +1166,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1102
1166
fn opendir ( & mut self , name_op : & OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , Scalar < Tag > > {
1103
1167
let this = self . eval_context_mut ( ) ;
1104
1168
1105
- this. check_no_isolation ( "`opendir`" ) ?;
1169
+ // Reject if isolation is enabled.
1170
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1171
+ this. reject_in_isolation ( "`opendir`" , reject_with) ?;
1172
+ // opendir function never sets "EPERM". Set "ENOENT".
1173
+ this. set_last_error_from_io_error ( ErrorKind :: NotFound ) ?;
1174
+ return Ok ( Scalar :: null_ptr ( this) ) ;
1175
+ }
1106
1176
1107
1177
let name = this. read_path_from_c_str ( this. read_scalar ( name_op) ?. check_init ( ) ?) ?;
1108
1178
@@ -1133,7 +1203,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1133
1203
let this = self . eval_context_mut ( ) ;
1134
1204
1135
1205
this. assert_target_os ( "linux" , "readdir64_r" ) ;
1136
- this. check_no_isolation ( "`readdir64_r`" ) ?;
1206
+
1207
+ // Reject if isolation is enabled.
1208
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1209
+ this. reject_in_isolation ( "`readdir64_r`" , reject_with) ?;
1210
+ // Set error code as "EBADF" (bad fd)
1211
+ return this. handle_not_found ( ) ;
1212
+ }
1137
1213
1138
1214
let dirp = this. read_scalar ( dirp_op) ?. to_machine_usize ( this) ?;
1139
1215
@@ -1222,7 +1298,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1222
1298
let this = self . eval_context_mut ( ) ;
1223
1299
1224
1300
this. assert_target_os ( "macos" , "readdir_r" ) ;
1225
- this. check_no_isolation ( "`readdir_r`" ) ?;
1301
+
1302
+ // Reject if isolation is enabled.
1303
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1304
+ this. reject_in_isolation ( "`readdir_r`" , reject_with) ?;
1305
+ // Set error code as "EBADF" (bad fd)
1306
+ return this. handle_not_found ( ) ;
1307
+ }
1226
1308
1227
1309
let dirp = this. read_scalar ( dirp_op) ?. to_machine_usize ( this) ?;
1228
1310
@@ -1307,7 +1389,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1307
1389
fn closedir ( & mut self , dirp_op : & OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
1308
1390
let this = self . eval_context_mut ( ) ;
1309
1391
1310
- this. check_no_isolation ( "`closedir`" ) ?;
1392
+ // Reject if isolation is enabled.
1393
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1394
+ this. reject_in_isolation ( "`closedir`" , reject_with) ?;
1395
+ // Set error code as "EBADF" (bad fd)
1396
+ return this. handle_not_found ( ) ;
1397
+ }
1311
1398
1312
1399
let dirp = this. read_scalar ( dirp_op) ?. to_machine_usize ( this) ?;
1313
1400
@@ -1326,7 +1413,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1326
1413
) -> InterpResult < ' tcx , i32 > {
1327
1414
let this = self . eval_context_mut ( ) ;
1328
1415
1329
- this. check_no_isolation ( "`ftruncate64`" ) ?;
1416
+ // Reject if isolation is enabled.
1417
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1418
+ this. reject_in_isolation ( "`ftruncate64`" , reject_with) ?;
1419
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
1420
+ return Ok ( -1 ) ;
1421
+ }
1330
1422
1331
1423
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
1332
1424
let length = this. read_scalar ( length_op) ?. to_i64 ( ) ?;
@@ -1361,7 +1453,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1361
1453
1362
1454
let this = self . eval_context_mut ( ) ;
1363
1455
1364
- this. check_no_isolation ( "`fsync`" ) ?;
1456
+ // Reject if isolation is enabled.
1457
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1458
+ this. reject_in_isolation ( "`fsync`" , reject_with) ?;
1459
+ // Set error code as "EBADF" (bad fd)
1460
+ return this. handle_not_found ( ) ;
1461
+ }
1365
1462
1366
1463
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
1367
1464
if let Some ( file_descriptor) = this. machine . file_handler . handles . get ( & fd) {
@@ -1377,7 +1474,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1377
1474
fn fdatasync ( & mut self , fd_op : & OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
1378
1475
let this = self . eval_context_mut ( ) ;
1379
1476
1380
- this. check_no_isolation ( "`fdatasync`" ) ?;
1477
+ // Reject if isolation is enabled.
1478
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1479
+ this. reject_in_isolation ( "`fdatasync`" , reject_with) ?;
1480
+ // Set error code as "EBADF" (bad fd)
1481
+ return this. handle_not_found ( ) ;
1482
+ }
1381
1483
1382
1484
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
1383
1485
if let Some ( file_descriptor) = this. machine . file_handler . handles . get ( & fd) {
@@ -1399,7 +1501,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1399
1501
) -> InterpResult < ' tcx , i32 > {
1400
1502
let this = self . eval_context_mut ( ) ;
1401
1503
1402
- this. check_no_isolation ( "`sync_file_range`" ) ?;
1504
+ // Reject if isolation is enabled.
1505
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1506
+ this. reject_in_isolation ( "`sync_file_range`" , reject_with) ?;
1507
+ // Set error code as "EBADF" (bad fd)
1508
+ return this. handle_not_found ( ) ;
1509
+ }
1403
1510
1404
1511
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
1405
1512
let offset = this. read_scalar ( offset_op) ?. to_i64 ( ) ?;
@@ -1438,7 +1545,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1438
1545
) -> InterpResult < ' tcx , i64 > {
1439
1546
let this = self . eval_context_mut ( ) ;
1440
1547
1441
- this. check_no_isolation ( "readlink" ) ?;
1548
+ // Reject if isolation is enabled.
1549
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1550
+ this. reject_in_isolation ( "`readlink`" , reject_with) ?;
1551
+ // readlink never sets "EPERM". Set "ENOENT".
1552
+ this. set_last_error_from_io_error ( ErrorKind :: NotFound ) ?;
1553
+ return Ok ( -1 ) ;
1554
+ }
1442
1555
1443
1556
let pathname = this. read_path_from_c_str ( this. read_scalar ( pathname_op) ?. check_init ( ) ?) ?;
1444
1557
let buf = this. read_scalar ( buf_op) ?. check_init ( ) ?;
0 commit comments