@@ -64,57 +64,55 @@ pub struct Config<'a> {
6464fn mknod ( file_name : & str , config : Config ) -> i32 {
6565 let c_str = CString :: new ( file_name) . expect ( "Failed to convert to CString" ) ;
6666
67- unsafe {
68- // set umask to 0 and store previous umask
69- let have_prev_umask = if config. use_umask {
67+ let errno = {
68+ // Use UmaskGuard to ensure umask is restored even on panic
69+ let _guard = if config. use_umask {
7070 None
7171 } else {
72- Some ( libc :: umask ( 0 ) )
72+ Some ( uucore :: mode :: UmaskGuard :: set ( 0 ) )
7373 } ;
7474
75- let errno = libc:: mknod ( c_str. as_ptr ( ) , config. mode , config. dev ) ;
75+ // SAFETY: mknod is a standard POSIX syscall. The c_str pointer is valid
76+ // for the duration of the call.
77+ unsafe { libc:: mknod ( c_str. as_ptr ( ) , config. mode , config. dev ) }
78+ } ; // Guard dropped here, restoring umask
7679
77- // set umask back to original value
78- if let Some ( prev_umask) = have_prev_umask {
79- libc:: umask ( prev_umask) ;
80- }
81-
82- if errno == -1 {
83- let c_str = CString :: new ( uucore:: execution_phrase ( ) . as_bytes ( ) )
84- . expect ( "Failed to convert to CString" ) ;
85- // shows the error from the mknod syscall
80+ if errno == -1 {
81+ let c_str = CString :: new ( uucore:: execution_phrase ( ) . as_bytes ( ) )
82+ . expect ( "Failed to convert to CString" ) ;
83+ // shows the error from the mknod syscall
84+ // SAFETY: perror is a standard C function that doesn't store the pointer
85+ unsafe {
8686 libc:: perror ( c_str. as_ptr ( ) ) ;
8787 }
88+ }
8889
89- // Apply SELinux context if requested
90- #[ cfg( feature = "selinux" ) ]
91- if config. set_security_context {
92- if let Err ( e) = uucore:: selinux:: set_selinux_security_context (
93- std:: path:: Path :: new ( file_name) ,
94- config. context ,
95- ) {
96- // if it fails, delete the file
97- let _ = std:: fs:: remove_dir ( file_name) ;
98- eprintln ! ( "{}: {}" , uucore:: util_name( ) , e) ;
99- return 1 ;
100- }
90+ // Apply SELinux context if requested
91+ #[ cfg( feature = "selinux" ) ]
92+ if config. set_security_context {
93+ if let Err ( e) = uucore:: selinux:: set_selinux_security_context (
94+ std:: path:: Path :: new ( file_name) ,
95+ config. context ,
96+ ) {
97+ // if it fails, delete the file
98+ let _ = std:: fs:: remove_dir ( file_name) ;
99+ eprintln ! ( "{}: {}" , uucore:: util_name( ) , e) ;
100+ return 1 ;
101101 }
102+ }
102103
103- // Apply SMACK context if requested
104- #[ cfg( feature = "smack" ) ]
105- if config. set_security_context {
106- if let Err ( e) =
107- uucore:: smack:: set_smack_label_and_cleanup ( file_name, config. context , |p| {
108- std:: fs:: remove_file ( p)
109- } )
110- {
111- eprintln ! ( "{}: {}" , uucore:: util_name( ) , e) ;
112- return 1 ;
113- }
104+ // Apply SMACK context if requested
105+ #[ cfg( feature = "smack" ) ]
106+ if config. set_security_context {
107+ if let Err ( e) = uucore:: smack:: set_smack_label_and_cleanup ( file_name, config. context , |p| {
108+ std:: fs:: remove_file ( p)
109+ } ) {
110+ eprintln ! ( "{}: {}" , uucore:: util_name( ) , e) ;
111+ return 1 ;
114112 }
115-
116- errno
117113 }
114+
115+ errno
118116}
119117
120118#[ uucore:: main]
0 commit comments