@@ -289,7 +289,14 @@ impl Env {
289289 let exec_file_path = canonicalize ( exec_file)
290290 . map_err ( |err| JailerError :: Canonicalize ( PathBuf :: from ( exec_file) , err) ) ?;
291291
292- if !exec_file_path. is_file ( ) {
292+ // Safety: the `canonicalize` call above ensured the existance of the path.
293+ let metadata = std:: fs:: metadata ( & exec_file_path) . unwrap ( ) ;
294+
295+ // Check that it is executable
296+ if metadata. permissions ( ) . mode ( ) & 0o111 == 0 {
297+ return Err ( JailerError :: NotExecutable ( exec_file_path) ) ;
298+ }
299+ if !metadata. is_file ( ) {
293300 return Err ( JailerError :: NotAFile ( exec_file_path) ) ;
294301 }
295302
@@ -782,7 +789,8 @@ mod tests {
782789 pub fn new ( pseudo_exec_file_path : & ' a str ) -> ArgVals < ' a > {
783790 let pseudo_exec_file_dir = Path :: new ( & pseudo_exec_file_path) . parent ( ) . unwrap ( ) ;
784791 fs:: create_dir_all ( pseudo_exec_file_dir) . unwrap ( ) ;
785- File :: create ( pseudo_exec_file_path) . unwrap ( ) ;
792+ create_exec_file ( pseudo_exec_file_path) ;
793+
786794 ArgVals {
787795 id : "bd65600d-8669-4903-8a14-af88203add38" ,
788796 exec_file : pseudo_exec_file_path,
@@ -799,6 +807,13 @@ mod tests {
799807 }
800808 }
801809
810+ fn create_exec_file ( pseudo_exec_file_path : & str ) {
811+ let exec = File :: create ( pseudo_exec_file_path) . unwrap ( ) ;
812+ let mut perms = exec. metadata ( ) . unwrap ( ) . permissions ( ) ;
813+ perms. set_mode ( 0o111 ) ;
814+ exec. set_permissions ( perms) . unwrap ( ) ;
815+ }
816+
802817 fn make_args ( arg_vals : & ArgVals ) -> Vec < String > {
803818 let mut arg_vec = vec ! [
804819 "--binary-name" ,
@@ -1018,31 +1033,30 @@ mod tests {
10181033 let pseudo_exec_file_path = get_pseudo_exec_file_path ( ) ;
10191034 let pseudo_exec_file_dir = Path :: new ( & pseudo_exec_file_path) . parent ( ) . unwrap ( ) ;
10201035 create_dir_all ( pseudo_exec_file_dir) . unwrap ( ) ;
1021- File :: create ( & pseudo_exec_file_path) . unwrap ( ) ;
1036+ create_exec_file ( & pseudo_exec_file_path) ;
10221037 Env :: validate_exec_file ( & pseudo_exec_file_path) . unwrap ( ) ;
10231038
10241039 // Error case 1: No such file exists
10251040 std:: fs:: remove_file ( & pseudo_exec_file_path) . unwrap ( ) ;
1026- assert_eq ! (
1027- format!(
1028- "{}" ,
1029- Env :: validate_exec_file( & pseudo_exec_file_path) . unwrap_err( )
1030- ) ,
1031- format!(
1032- "Failed to canonicalize path {}: No such file or directory (os error 2)" ,
1033- pseudo_exec_file_path
1034- )
1035- ) ;
1041+ assert ! ( matches!(
1042+ Env :: validate_exec_file( "/tmp/firecracker_test_dir/foobarbaz" ) ,
1043+ Err ( JailerError :: Canonicalize ( _, _) )
1044+ ) ) ;
10361045
10371046 // Error case 2: Not a file
10381047 std:: fs:: create_dir_all ( "/tmp/firecracker_test_dir" ) . unwrap ( ) ;
1039- assert_eq ! (
1040- format!(
1041- "{}" ,
1042- Env :: validate_exec_file( "/tmp/firecracker_test_dir" ) . unwrap_err( )
1043- ) ,
1044- "/tmp/firecracker_test_dir is not a file"
1045- ) ;
1048+ assert ! ( matches!(
1049+ Env :: validate_exec_file( "/tmp/firecracker_test_dir" ) ,
1050+ Err ( JailerError :: NotAFile ( _) )
1051+ ) ) ;
1052+
1053+ // Error case 3: Not an executable
1054+ File :: create ( "/tmp/firecracker_test_dir/foobarbaz" ) . unwrap ( ) ;
1055+ assert ! ( matches!(
1056+ Env :: validate_exec_file( "/tmp/firecracker_test_dir/foobarbaz" ) ,
1057+ Err ( JailerError :: NotExecutable ( _) )
1058+ ) ) ;
1059+ std:: fs:: remove_file ( "/tmp/firecracker_test_dir/foobarbaz" ) . unwrap ( ) ;
10461060
10471061 std:: fs:: remove_dir_all ( "/tmp/firecracker_test_dir" ) . unwrap ( ) ;
10481062 }
@@ -1181,7 +1195,7 @@ mod tests {
11811195 let exec_file_path = get_pseudo_exec_file_path ( ) ;
11821196 let exec_file_dir = Path :: new ( & exec_file_path) . parent ( ) . unwrap ( ) ;
11831197 fs:: create_dir_all ( exec_file_dir) . unwrap ( ) ;
1184- File :: create ( & exec_file_path) . unwrap ( ) ;
1198+ create_exec_file ( & exec_file_path) ;
11851199 let some_dir = TempDir :: new ( ) . unwrap ( ) ;
11861200 let some_dir_path = some_dir. as_path ( ) . to_str ( ) . unwrap ( ) ;
11871201
0 commit comments