@@ -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
@@ -505,7 +505,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
505
505
) -> InterpResult < ' tcx , i32 > {
506
506
let this = self . eval_context_mut ( ) ;
507
507
508
- this. check_no_isolation ( "`open`" ) ?;
508
+ // Reject if isolation is enabled.
509
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
510
+ this. reject_in_isolation ( "`open`" , reject_with) ?;
511
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
512
+ return Ok ( -1 ) ;
513
+ }
509
514
510
515
let flag = this. read_scalar ( flag_op) ?. to_i32 ( ) ?;
511
516
@@ -595,7 +600,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
595
600
fn fcntl ( & mut self , args : & [ OpTy < ' tcx , Tag > ] ) -> InterpResult < ' tcx , i32 > {
596
601
let this = self . eval_context_mut ( ) ;
597
602
598
- this. check_no_isolation ( "`fcntl`" ) ?;
603
+ // Reject if isolation is enabled.
604
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
605
+ this. reject_in_isolation ( "`fcntl`" , reject_with) ?;
606
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
607
+ return Ok ( -1 ) ;
608
+ }
599
609
600
610
if args. len ( ) < 2 {
601
611
throw_ub_format ! (
@@ -786,7 +796,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
786
796
fn unlink ( & mut self , path_op : & OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
787
797
let this = self . eval_context_mut ( ) ;
788
798
789
- this. check_no_isolation ( "`unlink`" ) ?;
799
+ // Reject if isolation is enabled.
800
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
801
+ this. reject_in_isolation ( "`unlink`" , reject_with) ?;
802
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
803
+ return Ok ( -1 ) ;
804
+ }
790
805
791
806
let path = this. read_path_from_c_str ( this. read_scalar ( path_op) ?. check_init ( ) ?) ?;
792
807
@@ -812,7 +827,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
812
827
813
828
let this = self . eval_context_mut ( ) ;
814
829
815
- this. check_no_isolation ( "`symlink`" ) ?;
830
+ // Reject if isolation is enabled.
831
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
832
+ this. reject_in_isolation ( "`symlink`" , reject_with) ?;
833
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
834
+ return Ok ( -1 ) ;
835
+ }
816
836
817
837
let target = this. read_path_from_c_str ( this. read_scalar ( target_op) ?. check_init ( ) ?) ?;
818
838
let linkpath = this. read_path_from_c_str ( this. read_scalar ( linkpath_op) ?. check_init ( ) ?) ?;
@@ -828,7 +848,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
828
848
) -> InterpResult < ' tcx , i32 > {
829
849
let this = self . eval_context_mut ( ) ;
830
850
this. assert_target_os ( "macos" , "stat" ) ;
831
- this. check_no_isolation ( "`stat`" ) ?;
851
+
852
+ // Reject if isolation is enabled.
853
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
854
+ this. reject_in_isolation ( "`stat`" , reject_with) ?;
855
+ // macos stat never sets "EPERM". Set error code "ENOENT".
856
+ this. set_last_error_from_io_error ( ErrorKind :: NotFound ) ?;
857
+ return Ok ( -1 ) ;
858
+ }
859
+
832
860
// `stat` always follows symlinks.
833
861
this. macos_stat_or_lstat ( true , path_op, buf_op)
834
862
}
@@ -841,7 +869,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
841
869
) -> InterpResult < ' tcx , i32 > {
842
870
let this = self . eval_context_mut ( ) ;
843
871
this. assert_target_os ( "macos" , "lstat" ) ;
844
- this. check_no_isolation ( "`lstat`" ) ?;
872
+
873
+ // Reject if isolation is enabled.
874
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
875
+ this. reject_in_isolation ( "`lstat`" , reject_with) ?;
876
+ // macos lstat never sets "EPERM". Set error code "ENOENT".
877
+ this. set_last_error_from_io_error ( ErrorKind :: NotFound ) ?;
878
+ return Ok ( -1 ) ;
879
+ }
880
+
845
881
this. macos_stat_or_lstat ( false , path_op, buf_op)
846
882
}
847
883
@@ -853,7 +889,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
853
889
let this = self . eval_context_mut ( ) ;
854
890
855
891
this. assert_target_os ( "macos" , "fstat" ) ;
856
- this. check_no_isolation ( "`fstat`" ) ?;
892
+
893
+ // Reject if isolation is enabled.
894
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
895
+ this. reject_in_isolation ( "`fstat`" , reject_with) ?;
896
+ // Set error code as "EBADF" (bad fd)
897
+ return this. handle_not_found ( ) ;
898
+ }
857
899
858
900
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
859
901
@@ -875,7 +917,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
875
917
let this = self . eval_context_mut ( ) ;
876
918
877
919
this. assert_target_os ( "linux" , "statx" ) ;
878
- this. check_no_isolation ( "`statx`" ) ?;
920
+
921
+ // Reject if isolation is enabled.
922
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
923
+ this. reject_in_isolation ( "`statx`" , reject_with) ?;
924
+ // statx never sets "EPERM". Set error code "ENOENT".
925
+ this. set_last_error_from_io_error ( ErrorKind :: NotFound ) ?;
926
+ return Ok ( -1 ) ;
927
+ }
879
928
880
929
let statxbuf_scalar = this. read_scalar ( statxbuf_op) ?. check_init ( ) ?;
881
930
let pathname_scalar = this. read_scalar ( pathname_op) ?. check_init ( ) ?;
@@ -1035,7 +1084,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1035
1084
) -> InterpResult < ' tcx , i32 > {
1036
1085
let this = self . eval_context_mut ( ) ;
1037
1086
1038
- this. check_no_isolation ( "`rename`" ) ?;
1087
+ // Reject if isolation is enabled.
1088
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1089
+ this. reject_in_isolation ( "`rename`" , reject_with) ?;
1090
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
1091
+ return Ok ( -1 ) ;
1092
+ }
1039
1093
1040
1094
let oldpath_scalar = this. read_scalar ( oldpath_op) ?. check_init ( ) ?;
1041
1095
let newpath_scalar = this. read_scalar ( newpath_op) ?. check_init ( ) ?;
@@ -1061,7 +1115,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1061
1115
) -> InterpResult < ' tcx , i32 > {
1062
1116
let this = self . eval_context_mut ( ) ;
1063
1117
1064
- this. check_no_isolation ( "`mkdir`" ) ?;
1118
+ // Reject if isolation is enabled.
1119
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1120
+ this. reject_in_isolation ( "`mkdir`" , reject_with) ?;
1121
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
1122
+ return Ok ( -1 ) ;
1123
+ }
1065
1124
1066
1125
#[ cfg_attr( not( unix) , allow( unused_variables) ) ]
1067
1126
let mode = if this. tcx . sess . target . os == "macos" {
@@ -1091,7 +1150,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1091
1150
fn rmdir ( & mut self , path_op : & OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
1092
1151
let this = self . eval_context_mut ( ) ;
1093
1152
1094
- this. check_no_isolation ( "`rmdir`" ) ?;
1153
+ // Reject if isolation is enabled.
1154
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1155
+ this. reject_in_isolation ( "`rmdir`" , reject_with) ?;
1156
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
1157
+ return Ok ( -1 ) ;
1158
+ }
1095
1159
1096
1160
let path = this. read_path_from_c_str ( this. read_scalar ( path_op) ?. check_init ( ) ?) ?;
1097
1161
@@ -1103,7 +1167,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1103
1167
fn opendir ( & mut self , name_op : & OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , Scalar < Tag > > {
1104
1168
let this = self . eval_context_mut ( ) ;
1105
1169
1106
- this. check_no_isolation ( "`opendir`" ) ?;
1170
+ // Reject if isolation is enabled.
1171
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1172
+ this. reject_in_isolation ( "`opendir`" , reject_with) ?;
1173
+ // opendir function never sets "EPERM". Set "ENOENT".
1174
+ this. set_last_error_from_io_error ( ErrorKind :: NotFound ) ?;
1175
+ return Ok ( Scalar :: null_ptr ( this) ) ;
1176
+ }
1107
1177
1108
1178
let name = this. read_path_from_c_str ( this. read_scalar ( name_op) ?. check_init ( ) ?) ?;
1109
1179
@@ -1134,7 +1204,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1134
1204
let this = self . eval_context_mut ( ) ;
1135
1205
1136
1206
this. assert_target_os ( "linux" , "readdir64_r" ) ;
1137
- this. check_no_isolation ( "`readdir64_r`" ) ?;
1207
+
1208
+ // Reject if isolation is enabled.
1209
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1210
+ this. reject_in_isolation ( "`readdir64_r`" , reject_with) ?;
1211
+ // Set error code as "EBADF" (bad fd)
1212
+ return this. handle_not_found ( ) ;
1213
+ }
1138
1214
1139
1215
let dirp = this. read_scalar ( dirp_op) ?. to_machine_usize ( this) ?;
1140
1216
@@ -1227,7 +1303,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1227
1303
let this = self . eval_context_mut ( ) ;
1228
1304
1229
1305
this. assert_target_os ( "macos" , "readdir_r" ) ;
1230
- this. check_no_isolation ( "`readdir_r`" ) ?;
1306
+
1307
+ // Reject if isolation is enabled.
1308
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1309
+ this. reject_in_isolation ( "`readdir_r`" , reject_with) ?;
1310
+ // Set error code as "EBADF" (bad fd)
1311
+ return this. handle_not_found ( ) ;
1312
+ }
1231
1313
1232
1314
let dirp = this. read_scalar ( dirp_op) ?. to_machine_usize ( this) ?;
1233
1315
@@ -1316,7 +1398,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1316
1398
fn closedir ( & mut self , dirp_op : & OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
1317
1399
let this = self . eval_context_mut ( ) ;
1318
1400
1319
- this. check_no_isolation ( "`closedir`" ) ?;
1401
+ // Reject if isolation is enabled.
1402
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1403
+ this. reject_in_isolation ( "`closedir`" , reject_with) ?;
1404
+ // Set error code as "EBADF" (bad fd)
1405
+ return this. handle_not_found ( ) ;
1406
+ }
1320
1407
1321
1408
let dirp = this. read_scalar ( dirp_op) ?. to_machine_usize ( this) ?;
1322
1409
@@ -1335,7 +1422,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1335
1422
) -> InterpResult < ' tcx , i32 > {
1336
1423
let this = self . eval_context_mut ( ) ;
1337
1424
1338
- this. check_no_isolation ( "`ftruncate64`" ) ?;
1425
+ // Reject if isolation is enabled.
1426
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1427
+ this. reject_in_isolation ( "`ftruncate64`" , reject_with) ?;
1428
+ this. set_last_error_from_io_error ( ErrorKind :: PermissionDenied ) ?;
1429
+ return Ok ( -1 ) ;
1430
+ }
1339
1431
1340
1432
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
1341
1433
let length = this. read_scalar ( length_op) ?. to_i64 ( ) ?;
@@ -1370,7 +1462,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1370
1462
1371
1463
let this = self . eval_context_mut ( ) ;
1372
1464
1373
- this. check_no_isolation ( "`fsync`" ) ?;
1465
+ // Reject if isolation is enabled.
1466
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1467
+ this. reject_in_isolation ( "`fsync`" , reject_with) ?;
1468
+ // Set error code as "EBADF" (bad fd)
1469
+ return this. handle_not_found ( ) ;
1470
+ }
1374
1471
1375
1472
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
1376
1473
if let Some ( file_descriptor) = this. machine . file_handler . handles . get ( & fd) {
@@ -1386,7 +1483,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1386
1483
fn fdatasync ( & mut self , fd_op : & OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
1387
1484
let this = self . eval_context_mut ( ) ;
1388
1485
1389
- this. check_no_isolation ( "`fdatasync`" ) ?;
1486
+ // Reject if isolation is enabled.
1487
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1488
+ this. reject_in_isolation ( "`fdatasync`" , reject_with) ?;
1489
+ // Set error code as "EBADF" (bad fd)
1490
+ return this. handle_not_found ( ) ;
1491
+ }
1390
1492
1391
1493
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
1392
1494
if let Some ( file_descriptor) = this. machine . file_handler . handles . get ( & fd) {
@@ -1408,7 +1510,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1408
1510
) -> InterpResult < ' tcx , i32 > {
1409
1511
let this = self . eval_context_mut ( ) ;
1410
1512
1411
- this. check_no_isolation ( "`sync_file_range`" ) ?;
1513
+ // Reject if isolation is enabled.
1514
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1515
+ this. reject_in_isolation ( "`sync_file_range`" , reject_with) ?;
1516
+ // Set error code as "EBADF" (bad fd)
1517
+ return this. handle_not_found ( ) ;
1518
+ }
1412
1519
1413
1520
let fd = this. read_scalar ( fd_op) ?. to_i32 ( ) ?;
1414
1521
let offset = this. read_scalar ( offset_op) ?. to_i64 ( ) ?;
@@ -1447,7 +1554,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1447
1554
) -> InterpResult < ' tcx , i64 > {
1448
1555
let this = self . eval_context_mut ( ) ;
1449
1556
1450
- this. check_no_isolation ( "readlink" ) ?;
1557
+ // Reject if isolation is enabled.
1558
+ if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
1559
+ this. reject_in_isolation ( "`readlink`" , reject_with) ?;
1560
+ // readlink never sets "EPERM". Set "ENOENT".
1561
+ this. set_last_error_from_io_error ( ErrorKind :: NotFound ) ?;
1562
+ return Ok ( -1 ) ;
1563
+ }
1451
1564
1452
1565
let pathname = this. read_path_from_c_str ( this. read_scalar ( pathname_op) ?. check_init ( ) ?) ?;
1453
1566
let buf = this. read_scalar ( buf_op) ?. check_init ( ) ?;
0 commit comments