@@ -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_pointer ( path_op) ?) ?;
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_pointer ( target_op) ?) ?;
817
837
let linkpath = this. read_path_from_c_str ( this. read_pointer ( linkpath_op) ?) ?;
@@ -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_ptr = this. read_pointer ( statxbuf_op) ?;
880
929
let pathname_ptr = this. read_pointer ( pathname_op) ?;
@@ -1032,7 +1081,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1032
1081
) -> InterpResult < ' tcx , i32 > {
1033
1082
let this = self . eval_context_mut ( ) ;
1034
1083
1035
- this. check_no_isolation ( "`rename`" ) ?;
1084
+ // Reject if isolation is enabled.
1085
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1086
+ this. reject_in_isolation ( "`rename`" , reject_with) ?;
1087
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
1088
+ return Ok ( -1 ) ;
1089
+ }
1036
1090
1037
1091
let oldpath_ptr = this. read_pointer ( oldpath_op) ?;
1038
1092
let newpath_ptr = this. read_pointer ( newpath_op) ?;
@@ -1058,7 +1112,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1058
1112
) -> InterpResult < ' tcx , i32 > {
1059
1113
let this = self . eval_context_mut ( ) ;
1060
1114
1061
- this. check_no_isolation ( "`mkdir`" ) ?;
1115
+ // Reject if isolation is enabled.
1116
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1117
+ this. reject_in_isolation ( "`mkdir`" , reject_with) ?;
1118
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
1119
+ return Ok ( -1 ) ;
1120
+ }
1062
1121
1063
1122
#[ cfg_attr( not( unix) , allow( unused_variables) ) ]
1064
1123
let mode = if this. tcx . sess . target . os == "macos" {
@@ -1088,7 +1147,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1088
1147
fn rmdir ( & mut self , path_op : & OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
1089
1148
let this = self . eval_context_mut ( ) ;
1090
1149
1091
- this. check_no_isolation ( "`rmdir`" ) ?;
1150
+ // Reject if isolation is enabled.
1151
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1152
+ this. reject_in_isolation ( "`rmdir`" , reject_with) ?;
1153
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
1154
+ return Ok ( -1 ) ;
1155
+ }
1092
1156
1093
1157
let path = this. read_path_from_c_str ( this. read_pointer ( path_op) ?) ?;
1094
1158
@@ -1100,7 +1164,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1100
1164
fn opendir ( & mut self , name_op : & OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , Scalar < Tag > > {
1101
1165
let this = self . eval_context_mut ( ) ;
1102
1166
1103
- this. check_no_isolation ( "`opendir`" ) ?;
1167
+ // Reject if isolation is enabled.
1168
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1169
+ this. reject_in_isolation ( "`opendir`" , reject_with) ?;
1170
+ // opendir function never sets "EPERM". Set "ENOENT".
1171
+ this. set_last_error_from_io_error ( ErrorKind :: NotFound ) ?;
1172
+ return Ok ( Scalar :: null_ptr ( this) ) ;
1173
+ }
1104
1174
1105
1175
let name = this. read_path_from_c_str ( this. read_pointer ( name_op) ?) ?;
1106
1176
@@ -1131,7 +1201,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1131
1201
let this = self . eval_context_mut ( ) ;
1132
1202
1133
1203
this. assert_target_os ( "linux" , "readdir64_r" ) ;
1134
- this. check_no_isolation ( "`readdir64_r`" ) ?;
1204
+
1205
+ // Reject if isolation is enabled.
1206
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1207
+ this. reject_in_isolation ( "`readdir64_r`" , reject_with) ?;
1208
+ // Set error code as "EBADF" (bad fd)
1209
+ return this. handle_not_found ( ) ;
1210
+ }
1135
1211
1136
1212
let dirp = this. read_scalar ( dirp_op) ?. to_machine_usize ( this) ?;
1137
1213
@@ -1224,7 +1300,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1224
1300
let this = self . eval_context_mut ( ) ;
1225
1301
1226
1302
this. assert_target_os ( "macos" , "readdir_r" ) ;
1227
- this. check_no_isolation ( "`readdir_r`" ) ?;
1303
+
1304
+ // Reject if isolation is enabled.
1305
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1306
+ this. reject_in_isolation ( "`readdir_r`" , reject_with) ?;
1307
+ // Set error code as "EBADF" (bad fd)
1308
+ return this. handle_not_found ( ) ;
1309
+ }
1228
1310
1229
1311
let dirp = this. read_scalar ( dirp_op) ?. to_machine_usize ( this) ?;
1230
1312
@@ -1313,7 +1395,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1313
1395
fn closedir ( & mut self , dirp_op : & OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
1314
1396
let this = self . eval_context_mut ( ) ;
1315
1397
1316
- this. check_no_isolation ( "`closedir`" ) ?;
1398
+ // Reject if isolation is enabled.
1399
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1400
+ this. reject_in_isolation ( "`closedir`" , reject_with) ?;
1401
+ // Set error code as "EBADF" (bad fd)
1402
+ return this. handle_not_found ( ) ;
1403
+ }
1317
1404
1318
1405
let dirp = this. read_scalar ( dirp_op) ?. to_machine_usize ( this) ?;
1319
1406
@@ -1332,7 +1419,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1332
1419
) -> InterpResult < ' tcx , i32 > {
1333
1420
let this = self . eval_context_mut ( ) ;
1334
1421
1335
- this. check_no_isolation ( "`ftruncate64`" ) ?;
1422
+ // Reject if isolation is enabled.
1423
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1424
+ this. reject_in_isolation ( "`ftruncate64`" , reject_with) ?;
1425
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
1426
+ return Ok ( -1 ) ;
1427
+ }
1336
1428
1337
1429
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
1338
1430
let length = this. read_scalar ( length_op) ?. to_i64 ( ) ?;
@@ -1367,7 +1459,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1367
1459
1368
1460
let this = self . eval_context_mut ( ) ;
1369
1461
1370
- this. check_no_isolation ( "`fsync`" ) ?;
1462
+ // Reject if isolation is enabled.
1463
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1464
+ this. reject_in_isolation ( "`fsync`" , reject_with) ?;
1465
+ // Set error code as "EBADF" (bad fd)
1466
+ return this. handle_not_found ( ) ;
1467
+ }
1371
1468
1372
1469
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
1373
1470
if let Some ( file_descriptor) = this. machine . file_handler . handles . get ( & fd) {
@@ -1383,7 +1480,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1383
1480
fn fdatasync ( & mut self , fd_op : & OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
1384
1481
let this = self . eval_context_mut ( ) ;
1385
1482
1386
- this. check_no_isolation ( "`fdatasync`" ) ?;
1483
+ // Reject if isolation is enabled.
1484
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1485
+ this. reject_in_isolation ( "`fdatasync`" , reject_with) ?;
1486
+ // Set error code as "EBADF" (bad fd)
1487
+ return this. handle_not_found ( ) ;
1488
+ }
1387
1489
1388
1490
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
1389
1491
if let Some ( file_descriptor) = this. machine . file_handler . handles . get ( & fd) {
@@ -1405,7 +1507,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1405
1507
) -> InterpResult < ' tcx , i32 > {
1406
1508
let this = self . eval_context_mut ( ) ;
1407
1509
1408
- this. check_no_isolation ( "`sync_file_range`" ) ?;
1510
+ // Reject if isolation is enabled.
1511
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1512
+ this. reject_in_isolation ( "`sync_file_range`" , reject_with) ?;
1513
+ // Set error code as "EBADF" (bad fd)
1514
+ return this. handle_not_found ( ) ;
1515
+ }
1409
1516
1410
1517
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
1411
1518
let offset = this. read_scalar ( offset_op) ?. to_i64 ( ) ?;
@@ -1444,7 +1551,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1444
1551
) -> InterpResult < ' tcx , i64 > {
1445
1552
let this = self . eval_context_mut ( ) ;
1446
1553
1447
- this. check_no_isolation ( "readlink" ) ?;
1554
+ // Reject if isolation is enabled.
1555
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1556
+ this. reject_in_isolation ( "`readlink`" , reject_with) ?;
1557
+ // readlink never sets "EPERM". Set "ENOENT".
1558
+ this. set_last_error_from_io_error ( ErrorKind :: NotFound ) ?;
1559
+ return Ok ( -1 ) ;
1560
+ }
1448
1561
1449
1562
let pathname = this. read_path_from_c_str ( this. read_pointer ( pathname_op) ?) ?;
1450
1563
let buf = this. read_pointer ( buf_op) ?;
0 commit comments