Fix TCGETS/TCSETS using wrong termios type definition
This commit is contained in:
		
							parent
							
								
									79bacb8bf4
								
							
						
					
					
						commit
						f65bbdd924
					
				| @ -26,11 +26,31 @@ pub struct IfReq { | ||||
|     pub ifr_union: [u8; 24], | ||||
| } | ||||
| 
 | ||||
| /* | ||||
|  The termios structure used in the Linux kernel is not the same as we use in the glibc. Thus, we have two | ||||
|  definitions here. | ||||
| */ | ||||
| 
 | ||||
| const KERNEL_NCCS: usize = 19; | ||||
| const NCCS: usize = 32; | ||||
| 
 | ||||
| type TcflagT = u32; | ||||
| type CcT = u8; | ||||
| type SpeedT = u32; | ||||
| const NCCS: usize = 32; | ||||
| #[derive(Debug)] | ||||
| 
 | ||||
| // Corresponds to the definition in glibc: sysdeps/unix/sysv/linux/kernel_termios.h
 | ||||
| #[derive(Debug, Default, Copy, Clone)] | ||||
| #[repr(C)] | ||||
| pub struct KernelTermios { | ||||
|     pub c_iflag: TcflagT, | ||||
|     pub c_oflag: TcflagT, | ||||
|     pub c_cflag: TcflagT, | ||||
|     pub c_lflag: TcflagT, | ||||
|     pub c_line: CcT, | ||||
|     pub c_cc: [CcT; KERNEL_NCCS], | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Default, Copy, Clone)] | ||||
| #[repr(C)] | ||||
| pub struct Termios { | ||||
|     pub c_iflag: TcflagT, | ||||
| @ -42,3 +62,75 @@ pub struct Termios { | ||||
|     pub c_ispeed: SpeedT, | ||||
|     pub c_ospeed: SpeedT, | ||||
| } | ||||
| 
 | ||||
| impl KernelTermios { | ||||
|     fn to_termios(&self) -> Termios { | ||||
|         let mut c_cc = [0; NCCS]; | ||||
|         c_cc[..KERNEL_NCCS].copy_from_slice(&self.c_cc); | ||||
|         Termios { | ||||
|             c_iflag: self.c_iflag, | ||||
|             c_oflag: self.c_oflag, | ||||
|             c_cflag: self.c_cflag, | ||||
|             c_lflag: self.c_lflag, | ||||
|             c_line: self.c_line, | ||||
|             c_cc: c_cc, | ||||
|             c_ispeed: 0, | ||||
|             c_ospeed: 0, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn execute_tcgets(&mut self, host_fd: i32, cmd_num: i32) -> Result<i32> { | ||||
|         debug_assert!(cmd_num == 0x5401); | ||||
|         let mut termios = self.to_termios(); | ||||
|         let len = std::mem::size_of::<Termios>(); | ||||
|         let ret = try_libc!({ | ||||
|             let mut retval: i32 = 0; | ||||
|             let status = occlum_ocall_ioctl( | ||||
|                 &mut retval as *mut i32, | ||||
|                 host_fd, | ||||
|                 cmd_num, | ||||
|                 &mut termios as *const Termios as *mut c_void, | ||||
|                 len, | ||||
|             ); | ||||
|             assert!(status == sgx_status_t::SGX_SUCCESS); | ||||
|             retval | ||||
|         }); | ||||
|         *self = termios.to_kernel_termios(); | ||||
|         Ok(ret) | ||||
|     } | ||||
| 
 | ||||
|     pub fn execute_tcsets(&self, host_fd: i32, cmd_num: i32) -> Result<i32> { | ||||
|         debug_assert!(cmd_num == 0x5402); | ||||
|         let termios = self.to_termios(); | ||||
|         let len = std::mem::size_of::<Termios>(); | ||||
|         let ret = try_libc!({ | ||||
|             let mut retval: i32 = 0; | ||||
|             let status = occlum_ocall_ioctl( | ||||
|                 &mut retval as *mut i32, | ||||
|                 host_fd, | ||||
|                 cmd_num, | ||||
|                 &termios as *const Termios as *mut c_void, | ||||
|                 len, | ||||
|             ); | ||||
|             assert!(status == sgx_status_t::SGX_SUCCESS); | ||||
|             retval | ||||
|         }); | ||||
|         Ok(ret) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Termios { | ||||
|     pub fn to_kernel_termios(&self) -> KernelTermios { | ||||
|         let mut c_cc = [0; KERNEL_NCCS]; | ||||
|         c_cc.copy_from_slice(&self.c_cc[..KERNEL_NCCS]); | ||||
| 
 | ||||
|         KernelTermios { | ||||
|             c_iflag: self.c_iflag, | ||||
|             c_oflag: self.c_oflag, | ||||
|             c_cflag: self.c_cflag, | ||||
|             c_lflag: self.c_lflag, | ||||
|             c_line: self.c_line, | ||||
|             c_cc: c_cc, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -27,8 +27,8 @@ impl_ioctl_nums_and_cmds! { | ||||
|     // ioctl_name => (ioctl_num, ioctl_type_arg)
 | ||||
| 
 | ||||
|     // Get terminal attributes
 | ||||
|     TCGETS => (0x5401, mut Termios), // ignore
 | ||||
|     TCSETS => (0x5402, Termios), | ||||
|     TCGETS => (0x5401, mut KernelTermios), // ignore
 | ||||
|     TCSETS => (0x5402, KernelTermios), | ||||
|     // Get window size
 | ||||
|     TIOCGWINSZ => (0x5413, mut WinSize), | ||||
|     // Set window size
 | ||||
|  | ||||
| @ -170,9 +170,22 @@ impl File for StdoutFile { | ||||
|     } | ||||
| 
 | ||||
|     fn ioctl(&self, cmd: &mut IoctlCmd) -> Result<i32> { | ||||
|         let host_stdout_fd = self.host_fd() as i32; | ||||
|         let cmd_bits = cmd.cmd_num() as c_int; | ||||
| 
 | ||||
|         // Handle special case for TCGETS/TCSETS which use different structures
 | ||||
|         // in linux kernel and libc
 | ||||
|         match cmd { | ||||
|             IoctlCmd::TCGETS(kernel_termios) => { | ||||
|                 return kernel_termios.execute_tcgets(host_stdout_fd, cmd_bits); | ||||
|             } | ||||
|             IoctlCmd::TCSETS(kernel_termios) => { | ||||
|                 return kernel_termios.execute_tcsets(host_stdout_fd, cmd_bits); | ||||
|             } | ||||
|             _ => {} | ||||
|         }; | ||||
| 
 | ||||
|         let can_delegate_to_host = match cmd { | ||||
|             IoctlCmd::TCGETS(_) => true, | ||||
|             IoctlCmd::TCSETS(_) => true, | ||||
|             IoctlCmd::TIOCGWINSZ(_) => true, | ||||
|             IoctlCmd::TIOCSWINSZ(_) => true, | ||||
|             _ => false, | ||||
| @ -181,9 +194,7 @@ impl File for StdoutFile { | ||||
|             return_errno!(EINVAL, "unknown ioctl cmd for stdout"); | ||||
|         } | ||||
| 
 | ||||
|         let cmd_bits = cmd.cmd_num() as c_int; | ||||
|         let cmd_arg_ptr = cmd.arg_ptr() as *mut c_void; | ||||
|         let host_stdout_fd = self.host_fd() as i32; | ||||
|         let cmd_arg_len = cmd.arg_len(); | ||||
|         let ret = try_libc!({ | ||||
|             let mut retval: i32 = 0; | ||||
| @ -321,9 +332,22 @@ impl File for StdinFile { | ||||
|     } | ||||
| 
 | ||||
|     fn ioctl(&self, cmd: &mut IoctlCmd) -> Result<i32> { | ||||
|         let host_stdin_fd = self.host_fd() as i32; | ||||
|         let cmd_bits = cmd.cmd_num() as c_int; | ||||
| 
 | ||||
|         // Handle special case for TCGETS/TCSETS which use different structures
 | ||||
|         // in linux kernel and libc
 | ||||
|         match cmd { | ||||
|             IoctlCmd::TCGETS(kernel_termios) => { | ||||
|                 return kernel_termios.execute_tcgets(host_stdin_fd, cmd_bits); | ||||
|             } | ||||
|             IoctlCmd::TCSETS(kernel_termios) => { | ||||
|                 return kernel_termios.execute_tcsets(host_stdin_fd, cmd_bits); | ||||
|             } | ||||
|             _ => {} | ||||
|         }; | ||||
| 
 | ||||
|         let can_delegate_to_host = match cmd { | ||||
|             IoctlCmd::TCGETS(_) => true, | ||||
|             IoctlCmd::TCSETS(_) => true, | ||||
|             IoctlCmd::TIOCGWINSZ(_) => true, | ||||
|             IoctlCmd::TIOCSWINSZ(_) => true, | ||||
|             _ => false, | ||||
| @ -332,9 +356,7 @@ impl File for StdinFile { | ||||
|             return_errno!(EINVAL, "unknown ioctl cmd for stdin"); | ||||
|         } | ||||
| 
 | ||||
|         let cmd_bits = cmd.cmd_num() as c_int; | ||||
|         let cmd_arg_ptr = cmd.arg_ptr() as *mut c_void; | ||||
|         let host_stdin_fd = self.host_fd() as i32; | ||||
|         let cmd_arg_len = cmd.arg_len(); | ||||
|         let ret = try_libc!({ | ||||
|             let mut retval: i32 = 0; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user