From 54afae9ed523ae03f6398570cab8ba02e822fe29 Mon Sep 17 00:00:00 2001 From: LI Qing Date: Tue, 9 Aug 2022 10:30:14 +0800 Subject: [PATCH] Fix the path length limit and update sefs --- deps/sefs | 2 +- src/libos/src/fs/file_ops/fspath.rs | 6 +++++ src/libos/src/fs/file_ops/getdents.rs | 2 +- src/libos/src/fs/syscalls.rs | 38 ++++++++++----------------- src/libos/src/net/socket/unix/addr.rs | 9 +++++-- 5 files changed, 29 insertions(+), 28 deletions(-) diff --git a/deps/sefs b/deps/sefs index 51ced28f..e4575ae6 160000 --- a/deps/sefs +++ b/deps/sefs @@ -1 +1 @@ -Subproject commit 51ced28f937c98418b91f97c85b744dacc223b0e +Subproject commit e4575ae61bf25b1426f1e7437e91e6ac5b52175e diff --git a/src/libos/src/fs/file_ops/fspath.rs b/src/libos/src/fs/file_ops/fspath.rs index e808e8c4..37549be9 100644 --- a/src/libos/src/fs/file_ops/fspath.rs +++ b/src/libos/src/fs/file_ops/fspath.rs @@ -23,6 +23,9 @@ enum FsPathInner<'a> { impl<'a> FsPath<'a> { /// Construct a FsPath pub fn new(path: &'a str, fd: i32, allow_empty_path: bool) -> Result { + if path.len() > PATH_MAX { + return_errno!(ENAMETOOLONG, "path name too long"); + } let fs_path_inner = if Path::new(path).is_absolute() { FsPathInner::Absolute(path) } else if fd >= 0 { @@ -83,6 +86,9 @@ impl<'a> FsPath<'a> { fs.cwd().to_owned() } }; + if abs_path.len() > PATH_MAX { + return_errno!(ENAMETOOLONG, "abs path too long"); + } Ok(abs_path) } } diff --git a/src/libos/src/fs/file_ops/getdents.rs b/src/libos/src/fs/file_ops/getdents.rs index 39f10c62..a5a928b3 100644 --- a/src/libos/src/fs/file_ops/getdents.rs +++ b/src/libos/src/fs/file_ops/getdents.rs @@ -67,7 +67,7 @@ impl<'a, T: Dirent> DirentWriter for DirentBufWriter<'a, T> { } } -trait Dirent { +trait Dirent: Sync + Send { fn new(name: &str, ino: u64, type_: FileType) -> Self; fn rec_len(&self) -> usize; fn dump(&self, buf: &mut [u8], name: &str, type_: FileType) -> Result<()>; diff --git a/src/libos/src/fs/syscalls.rs b/src/libos/src/fs/syscalls.rs index fb4838f9..33bc24ba 100644 --- a/src/libos/src/fs/syscalls.rs +++ b/src/libos/src/fs/syscalls.rs @@ -12,8 +12,6 @@ use super::*; use config::ConfigMountFsType; use util::mem_util::from_user; -pub const MAX_PATH_LEN: usize = 255; - #[allow(non_camel_case_types)] pub struct iovec_t { base: *const c_void, @@ -115,11 +113,6 @@ pub fn do_openat(dirfd: i32, path: *const i8, flags: u32, mode: u16) -> Result MAX_PATH_LEN { - return_errno!(ENAMETOOLONG, "path name too long"); - } let fs_path = FsPath::new(&path, dirfd, false)?; let mode = FileMode::from_bits_truncate(mode); let fd = file_ops::do_openat(&fs_path, flags, mode)?; @@ -382,7 +375,7 @@ pub fn do_chdir(path: *const i8) -> Result { .into_owned(); if path.is_empty() { return_errno!(ENOENT, "path is an empty string"); - } else if path.len() > MAX_PATH_LEN { + } else if path.len() > PATH_MAX { return_errno!(ENAMETOOLONG, "path name too long"); } fs_ops::do_chdir(&path)?; @@ -429,11 +422,6 @@ pub fn do_renameat( let newpath = from_user::clone_cstring_safely(newpath)? .to_string_lossy() .into_owned(); - if oldpath.is_empty() || newpath.is_empty() { - return_errno!(ENOENT, "oldpath or newpath is an empty string"); - } else if oldpath.len() > MAX_PATH_LEN || newpath.len() > MAX_PATH_LEN { - return_errno!(ENAMETOOLONG, "oldpath or newpath name too long"); - } let old_fs_path = FsPath::new(&oldpath, olddirfd, false)?; let new_fs_path = FsPath::new(&newpath, newdirfd, false)?; file_ops::do_renameat(&old_fs_path, &new_fs_path)?; @@ -448,11 +436,6 @@ pub fn do_mkdirat(dirfd: i32, path: *const i8, mode: u16) -> Result { let path = from_user::clone_cstring_safely(path)? .to_string_lossy() .into_owned(); - if path.is_empty() { - return_errno!(ENOENT, "path is an empty string"); - } else if path.len() > MAX_PATH_LEN { - return_errno!(ENAMETOOLONG, "path name too long"); - } let fs_path = FsPath::new(&path, dirfd, false)?; let mode = FileMode::from_bits_truncate(mode); file_ops::do_mkdirat(&fs_path, mode)?; @@ -465,7 +448,7 @@ pub fn do_rmdir(path: *const i8) -> Result { .into_owned(); if path.is_empty() { return_errno!(ENOENT, "path is an empty string"); - } else if path.len() > MAX_PATH_LEN { + } else if path.len() > PATH_MAX { return_errno!(ENAMETOOLONG, "path name too long"); } file_ops::do_rmdir(&path)?; @@ -558,11 +541,6 @@ pub fn do_fchmodat(dirfd: i32, path: *const i8, mode: u16) -> Result { let path = from_user::clone_cstring_safely(path)? .to_string_lossy() .into_owned(); - if path.is_empty() { - return_errno!(ENOENT, "path is an empty string"); - } else if path.len() > MAX_PATH_LEN { - return_errno!(ENAMETOOLONG, "path name too long"); - } let mode = FileMode::from_bits_truncate(mode); let fs_path = FsPath::new(&path, dirfd, false)?; file_ops::do_fchmodat(&fs_path, mode)?; @@ -681,6 +659,13 @@ pub fn do_statfs(path: *const i8, statfs_buf: *mut Statfs) -> Result { let path = from_user::clone_cstring_safely(path)? .to_string_lossy() .into_owned(); + if path.is_empty() { + return_errno!(ENOENT, "path is an empty string"); + } else if path.len() > PATH_MAX { + return_errno!(ENAMETOOLONG, "path name too long"); + } + from_user::check_mut_ptr(statfs_buf)?; + let statfs = fs_ops::do_statfs(&path)?; unsafe { statfs_buf.write(statfs); @@ -701,6 +686,11 @@ pub fn do_mount( let target = from_user::clone_cstring_safely(target)? .to_string_lossy() .into_owned(); + if target.is_empty() { + return_errno!(ENOENT, "target is an empty string"); + } else if target.len() > PATH_MAX { + return_errno!(ENAMETOOLONG, "target name too long"); + } let flags = MountFlags::from_bits(flags).ok_or_else(|| errno!(EINVAL, "invalid flags"))?; let mount_options = { let fs_type = { diff --git a/src/libos/src/net/socket/unix/addr.rs b/src/libos/src/net/socket/unix/addr.rs index c79a6f25..08925504 100644 --- a/src/libos/src/net/socket/unix/addr.rs +++ b/src/libos/src/net/socket/unix/addr.rs @@ -139,8 +139,13 @@ impl UnixPath { if self.inner.is_absolute() { path_str.to_string() } else { - let mut prefix = path_str.to_owned(); - prefix.push_str(self.cwd.as_ref().unwrap()); + let mut prefix = self.cwd.as_ref().unwrap().clone(); + if prefix.ends_with("/") { + prefix.push_str(path_str); + } else { + prefix.push_str("/"); + prefix.push_str(path_str); + } prefix } }