Browse Source

fix(driver): fix memory security problem in tty device ioctl (#833)

* add soft link to musl-gcc

* fix the tty_ioctl

* modified

* modified
laokengwt 9 months ago
parent
commit
415e14e9c3

+ 30 - 15
kernel/src/driver/tty/tty_device.rs

@@ -34,7 +34,7 @@ use crate::{
         spinlock::SpinLockGuard,
     },
     mm::VirtAddr,
-    net::event_poll::{EPollItem, EventPoll},
+    net::event_poll::{EPollItem, KernelIoctlData},
     process::ProcessManager,
     syscall::user_access::{UserBufferReader, UserBufferWriter},
 };
@@ -308,6 +308,35 @@ impl IndexNode for TtyDevice {
         Ok(())
     }
 
+    fn kernel_ioctl(
+        &self,
+        arg: Arc<dyn KernelIoctlData>,
+        data: &FilePrivateData,
+    ) -> Result<usize, SystemError> {
+        let epitem = arg
+            .arc_any()
+            .downcast::<EPollItem>()
+            .map_err(|_| SystemError::EFAULT)?;
+
+        let _ = UserBufferReader::new(
+            &epitem as *const Arc<EPollItem>,
+            core::mem::size_of::<Arc<EPollItem>>(),
+            false,
+        )?;
+
+        let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data {
+            (tty_priv.tty(), tty_priv.mode)
+        } else {
+            return Err(SystemError::EIO);
+        };
+
+        let core = tty.core();
+
+        core.add_epitem(epitem.clone());
+
+        return Ok(0);
+    }
+
     fn ioctl(&self, cmd: u32, arg: usize, data: &FilePrivateData) -> Result<usize, SystemError> {
         let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data {
             (tty_priv.tty(), tty_priv.mode)
@@ -326,20 +355,6 @@ impl IndexNode for TtyDevice {
                     todo!()
                 }
             }
-            EventPoll::ADD_EPOLLITEM => {
-                let _ = UserBufferReader::new(
-                    arg as *const Arc<EPollItem>,
-                    core::mem::size_of::<Arc<EPollItem>>(),
-                    false,
-                )?;
-                let epitem = unsafe { &*(arg as *const Arc<EPollItem>) };
-
-                let core = tty.core();
-
-                core.add_epitem(epitem.clone());
-
-                return Ok(0);
-            }
             _ => {}
         }
 

+ 1 - 5
kernel/src/filesystem/vfs/file.rs

@@ -492,11 +492,7 @@ impl File {
                 return inode.inner().lock().add_epoll(epitem);
             }
             _ => {
-                let r = self.inode.ioctl(
-                    EventPoll::ADD_EPOLLITEM,
-                    &epitem as *const Arc<EPollItem> as usize,
-                    &self.private_data.lock(),
-                );
+                let r = self.inode.kernel_ioctl(epitem, &self.private_data.lock());
                 if r.is_err() {
                     return Err(SystemError::ENOSYS);
                 }

+ 8 - 0
kernel/src/filesystem/vfs/mod.rs

@@ -350,6 +350,14 @@ pub trait IndexNode: Any + Sync + Send + Debug + CastFromSync {
         return Err(SystemError::ENOSYS);
     }
 
+    fn kernel_ioctl(
+        &self,
+        _arg: Arc<dyn crate::net::event_poll::KernelIoctlData>,
+        _data: &FilePrivateData,
+    ) -> Result<usize, SystemError> {
+        return Err(SystemError::ENOSYS);
+    }
+
     /// @brief 获取inode所在的文件系统的指针
     fn fs(&self) -> Arc<dyn FileSystem>;
 

+ 6 - 0
kernel/src/net/event_poll/mod.rs

@@ -1,4 +1,5 @@
 use core::{
+    any::Any,
     fmt::Debug,
     sync::atomic::{AtomicBool, Ordering},
 };
@@ -8,6 +9,7 @@ use alloc::{
     sync::{Arc, Weak},
     vec::Vec,
 };
+use intertrait::CastFromSync;
 use system_error::SystemError;
 
 use crate::{
@@ -130,6 +132,10 @@ impl EPollItem {
     }
 }
 
+pub trait KernelIoctlData: Send + Sync + Any + Debug + CastFromSync {}
+
+impl KernelIoctlData for EPollItem {}
+
 /// ### Epoll文件的私有信息
 #[derive(Debug, Clone)]
 pub struct EPollPrivateData {