@@ -6,7 +6,7 @@ use std::fs::{self, canonicalize, File, OpenOptions, Permissions};
6
6
use std:: io;
7
7
use std:: io:: Write ;
8
8
use std:: os:: unix:: fs:: PermissionsExt ;
9
- use std:: os:: unix:: io:: IntoRawFd ;
9
+ use std:: os:: unix:: io:: AsRawFd ;
10
10
use std:: os:: unix:: process:: CommandExt ;
11
11
use std:: path:: { Component , Path , PathBuf } ;
12
12
use std:: process:: { Command , Stdio } ;
@@ -43,8 +43,6 @@ const DEV_URANDOM_WITH_NUL: &[u8] = b"/dev/urandom\0";
43
43
const DEV_URANDOM_MAJOR : u32 = 1 ;
44
44
const DEV_URANDOM_MINOR : u32 = 9 ;
45
45
46
- const DEV_NULL_WITH_NUL : & [ u8 ] = b"/dev/null\0 " ;
47
-
48
46
// Relevant folders inside the jail that we create or/and for which we change ownership.
49
47
// We need /dev in order to be able to create /dev/kvm and /dev/net/tun device.
50
48
// We need /run for the default location of the api socket.
@@ -403,23 +401,13 @@ impl Env {
403
401
}
404
402
405
403
fn join_netns ( path : & str ) -> Result < ( ) > {
406
- // Not used `as_raw_fd` as it will create a dangling fd (object will be freed immediately)
407
- // instead used `into_raw_fd` which provides underlying fd ownership to caller.
408
- let netns_fd = File :: open ( path)
409
- . map_err ( |err| Error :: FileOpen ( PathBuf :: from ( path) , err) ) ?
410
- . into_raw_fd ( ) ;
411
-
412
- // SAFETY: Safe because we are passing valid parameters.
413
- SyscallReturnCode ( unsafe { libc:: setns ( netns_fd, libc:: CLONE_NEWNET ) } )
414
- . into_empty_result ( )
415
- . map_err ( Error :: SetNetNs ) ?;
404
+ // The fd backing the file will be automatically dropped at the end of the scope
405
+ let netns = File :: open ( path) . map_err ( |err| Error :: FileOpen ( PathBuf :: from ( path) , err) ) ?;
416
406
417
- // Since we have ownership here, we also have to close the fd after joining the
418
- // namespace.
419
407
// SAFETY: Safe because we are passing valid parameters.
420
- SyscallReturnCode ( unsafe { libc:: close ( netns_fd ) } )
408
+ SyscallReturnCode ( unsafe { libc:: setns ( netns . as_raw_fd ( ) , libc :: CLONE_NEWNET ) } )
421
409
. into_empty_result ( )
422
- . map_err ( Error :: CloseNetNsFd )
410
+ . map_err ( Error :: SetNetNs )
423
411
}
424
412
425
413
fn exec_command ( & self , chroot_exec_file : PathBuf ) -> io:: Error {
@@ -553,18 +541,7 @@ impl Env {
553
541
554
542
// If daemonization was requested, open /dev/null before chrooting.
555
543
let dev_null = if self . daemonize {
556
- Some (
557
- // SAFETY: Safe because we use a constant null-terminated string and verify the
558
- // result.
559
- SyscallReturnCode ( unsafe {
560
- libc:: open (
561
- DEV_NULL_WITH_NUL . as_ptr ( ) . cast :: < libc:: c_char > ( ) ,
562
- libc:: O_RDWR ,
563
- )
564
- } )
565
- . into_result ( )
566
- . map_err ( Error :: OpenDevNull ) ?,
567
- )
544
+ Some ( File :: open ( "/dev/null" ) . map_err ( Error :: OpenDevNull ) ?)
568
545
} else {
569
546
None
570
547
} ;
@@ -606,22 +583,17 @@ impl Env {
606
583
} ) ;
607
584
608
585
// Daemonize before exec, if so required (when the dev_null variable != None).
609
- if let Some ( fd ) = dev_null {
586
+ if let Some ( dev_null ) = dev_null {
610
587
// Call setsid().
611
588
// SAFETY: Safe because it's a library function.
612
589
SyscallReturnCode ( unsafe { libc:: setsid ( ) } )
613
590
. into_empty_result ( )
614
591
. map_err ( Error :: SetSid ) ?;
615
592
616
593
// Replace the stdio file descriptors with the /dev/null fd.
617
- dup2 ( fd, STDIN_FILENO ) ?;
618
- dup2 ( fd, STDOUT_FILENO ) ?;
619
- dup2 ( fd, STDERR_FILENO ) ?;
620
-
621
- // SAFETY: Safe because we are passing valid parameters, and checking the result.
622
- SyscallReturnCode ( unsafe { libc:: close ( fd) } )
623
- . into_empty_result ( )
624
- . map_err ( Error :: CloseDevNullFd ) ?;
594
+ dup2 ( dev_null. as_raw_fd ( ) , STDIN_FILENO ) ?;
595
+ dup2 ( dev_null. as_raw_fd ( ) , STDOUT_FILENO ) ?;
596
+ dup2 ( dev_null. as_raw_fd ( ) , STDERR_FILENO ) ?;
625
597
}
626
598
627
599
// If specified, exec the provided binary into a new PID namespace.
@@ -892,18 +864,11 @@ mod tests {
892
864
#[ test]
893
865
fn test_dup2 ( ) {
894
866
// Open /dev/kvm since it should be available anyway.
895
- let fd1 = fs:: File :: open ( "/dev/kvm" ) . unwrap ( ) . into_raw_fd ( ) ;
867
+ let file1 = fs:: File :: open ( "/dev/kvm" ) . unwrap ( ) ;
896
868
// We open a second file to make sure its associated fd is not used by something else.
897
- let fd2 = fs:: File :: open ( "/dev/kvm" ) . unwrap ( ) . into_raw_fd ( ) ;
869
+ let file2 = fs:: File :: open ( "/dev/kvm" ) . unwrap ( ) ;
898
870
899
- dup2 ( fd1, fd2) . unwrap ( ) ;
900
-
901
- unsafe {
902
- libc:: close ( fd1) ;
903
- }
904
- unsafe {
905
- libc:: close ( fd2) ;
906
- }
871
+ dup2 ( file1. as_raw_fd ( ) , file2. as_raw_fd ( ) ) . unwrap ( ) ;
907
872
}
908
873
909
874
#[ test]
0 commit comments