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], |     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 TcflagT = u32; | ||||||
| type CcT = u8; | type CcT = u8; | ||||||
| type SpeedT = u32; | 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)] | #[repr(C)] | ||||||
| pub struct Termios { | pub struct Termios { | ||||||
|     pub c_iflag: TcflagT, |     pub c_iflag: TcflagT, | ||||||
| @ -42,3 +62,75 @@ pub struct Termios { | |||||||
|     pub c_ispeed: SpeedT, |     pub c_ispeed: SpeedT, | ||||||
|     pub c_ospeed: 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)
 |     // ioctl_name => (ioctl_num, ioctl_type_arg)
 | ||||||
| 
 | 
 | ||||||
|     // Get terminal attributes
 |     // Get terminal attributes
 | ||||||
|     TCGETS => (0x5401, mut Termios), // ignore
 |     TCGETS => (0x5401, mut KernelTermios), // ignore
 | ||||||
|     TCSETS => (0x5402, Termios), |     TCSETS => (0x5402, KernelTermios), | ||||||
|     // Get window size
 |     // Get window size
 | ||||||
|     TIOCGWINSZ => (0x5413, mut WinSize), |     TIOCGWINSZ => (0x5413, mut WinSize), | ||||||
|     // Set window size
 |     // Set window size
 | ||||||
|  | |||||||
| @ -170,9 +170,22 @@ impl File for StdoutFile { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn ioctl(&self, cmd: &mut IoctlCmd) -> Result<i32> { |     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 { |         let can_delegate_to_host = match cmd { | ||||||
|             IoctlCmd::TCGETS(_) => true, |  | ||||||
|             IoctlCmd::TCSETS(_) => true, |  | ||||||
|             IoctlCmd::TIOCGWINSZ(_) => true, |             IoctlCmd::TIOCGWINSZ(_) => true, | ||||||
|             IoctlCmd::TIOCSWINSZ(_) => true, |             IoctlCmd::TIOCSWINSZ(_) => true, | ||||||
|             _ => false, |             _ => false, | ||||||
| @ -181,9 +194,7 @@ impl File for StdoutFile { | |||||||
|             return_errno!(EINVAL, "unknown ioctl cmd for stdout"); |             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 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 cmd_arg_len = cmd.arg_len(); | ||||||
|         let ret = try_libc!({ |         let ret = try_libc!({ | ||||||
|             let mut retval: i32 = 0; |             let mut retval: i32 = 0; | ||||||
| @ -321,9 +332,22 @@ impl File for StdinFile { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn ioctl(&self, cmd: &mut IoctlCmd) -> Result<i32> { |     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 { |         let can_delegate_to_host = match cmd { | ||||||
|             IoctlCmd::TCGETS(_) => true, |  | ||||||
|             IoctlCmd::TCSETS(_) => true, |  | ||||||
|             IoctlCmd::TIOCGWINSZ(_) => true, |             IoctlCmd::TIOCGWINSZ(_) => true, | ||||||
|             IoctlCmd::TIOCSWINSZ(_) => true, |             IoctlCmd::TIOCSWINSZ(_) => true, | ||||||
|             _ => false, |             _ => false, | ||||||
| @ -332,9 +356,7 @@ impl File for StdinFile { | |||||||
|             return_errno!(EINVAL, "unknown ioctl cmd for stdin"); |             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 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 cmd_arg_len = cmd.arg_len(); | ||||||
|         let ret = try_libc!({ |         let ret = try_libc!({ | ||||||
|             let mut retval: i32 = 0; |             let mut retval: i32 = 0; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user