diff --git a/src/scheme/initfs.rs b/src/scheme/initfs.rs index 24e58a64c4c404241bda6560ef7af6cd00243117..432e62af3deee910843fbd93b762e6e9ea872b5e 100644 --- a/src/scheme/initfs.rs +++ b/src/scheme/initfs.rs @@ -5,7 +5,7 @@ use spin::RwLock; use syscall::data::Stat; use syscall::error::*; -use syscall::flag::{MODE_DIR, MODE_FILE, SEEK_SET, SEEK_CUR, SEEK_END}; +use syscall::flag::{O_CLOEXEC, MODE_DIR, MODE_FILE, SEEK_SET, SEEK_CUR, SEEK_END}; use syscall::scheme::Scheme; #[cfg(test)] @@ -19,6 +19,7 @@ include!(concat!(env!("OUT_DIR"), "/gen.rs")); struct Handle { path: &'static [u8], + flags: usize, data: &'static [u8], mode: u16, seek: usize @@ -41,7 +42,7 @@ impl InitFsScheme { } impl Scheme for InitFsScheme { - fn open(&self, path: &[u8], _flags: usize, _uid: u32, _gid: u32) -> Result<usize> { + fn open(&self, path: &[u8], flags: usize, _uid: u32, _gid: u32) -> Result<usize> { let path_utf8 = str::from_utf8(path).or(Err(Error::new(ENOENT)))?; let path_trimmed = path_utf8.trim_matches('/'); @@ -51,6 +52,7 @@ impl Scheme for InitFsScheme { let id = self.next_id.fetch_add(1, Ordering::SeqCst); self.handles.write().insert(id, Handle { path: entry.0, + flags: flags, data: (entry.1).0, mode: if (entry.1).1 { MODE_DIR | 0o755 } else { MODE_FILE | 0o744 }, seek: 0 @@ -63,16 +65,21 @@ impl Scheme for InitFsScheme { Err(Error::new(ENOENT)) } - fn dup(&self, id: usize, _buf: &[u8]) -> Result<usize> { - let (path, data, mode, seek) = { + fn dup(&self, id: usize, buf: &[u8]) -> Result<usize> { + let (path, flags, data, mode, seek) = { let handles = self.handles.read(); let handle = handles.get(&id).ok_or(Error::new(EBADF))?; - (handle.path, handle.data, handle.mode, handle.seek) + (handle.path, handle.flags, handle.data, handle.mode, handle.seek) }; + if buf == b"exec" && flags & O_CLOEXEC == O_CLOEXEC { + return Err(Error::new(EBADF)); + } + let id = self.next_id.fetch_add(1, Ordering::SeqCst); self.handles.write().insert(id, Handle { path: path, + flags: flags, data: data, mode: mode, seek: seek diff --git a/src/scheme/root.rs b/src/scheme/root.rs index cd08fd365e5653e9196c0bc626f8dfbf6ae7ea05..644144ae9d2b8e4fafe3289f8a28d6a28a07c34d 100644 --- a/src/scheme/root.rs +++ b/src/scheme/root.rs @@ -6,6 +6,7 @@ use spin::RwLock; use context; use syscall::error::*; +use syscall::flag::O_CLOEXEC; use syscall::scheme::Scheme; use scheme::{self, SchemeNamespace, SchemeId}; use scheme::user::{UserInner, UserScheme}; @@ -58,13 +59,17 @@ impl Scheme for RootScheme { } } - fn dup(&self, file: usize, _buf: &[u8]) -> Result<usize> { + fn dup(&self, file: usize, buf: &[u8]) -> Result<usize> { let mut handles = self.handles.write(); let inner = { let inner = handles.get(&file).ok_or(Error::new(EBADF))?; inner.clone() }; + if buf == b"exec" && inner.flags & O_CLOEXEC == O_CLOEXEC { + return Err(Error::new(EBADF)); + } + let id = self.next_id.fetch_add(1, Ordering::SeqCst); handles.insert(id, inner); diff --git a/src/scheme/user.rs b/src/scheme/user.rs index cbfcac1f9232439c3fbb6a6149e5ea4db7bec079..db810451d842ef0e66f092e7a0d9718381569a53 100644 --- a/src/scheme/user.rs +++ b/src/scheme/user.rs @@ -21,7 +21,7 @@ pub struct UserInner { root_id: SchemeId, handle_id: usize, pub name: Box<[u8]>, - flags: usize, + pub flags: usize, pub scheme_id: AtomicSchemeId, next_id: AtomicU64, context: Weak<RwLock<Context>>,