Fix the path length limit and update sefs

This commit is contained in:
LI Qing 2022-08-09 10:30:14 +08:00 committed by volcano
parent f12f2c5499
commit 54afae9ed5
5 changed files with 29 additions and 28 deletions

2
deps/sefs vendored

@ -1 +1 @@
Subproject commit 51ced28f937c98418b91f97c85b744dacc223b0e Subproject commit e4575ae61bf25b1426f1e7437e91e6ac5b52175e

@ -23,6 +23,9 @@ enum FsPathInner<'a> {
impl<'a> FsPath<'a> { impl<'a> FsPath<'a> {
/// Construct a FsPath /// Construct a FsPath
pub fn new(path: &'a str, fd: i32, allow_empty_path: bool) -> Result<Self> { pub fn new(path: &'a str, fd: i32, allow_empty_path: bool) -> Result<Self> {
if path.len() > PATH_MAX {
return_errno!(ENAMETOOLONG, "path name too long");
}
let fs_path_inner = if Path::new(path).is_absolute() { let fs_path_inner = if Path::new(path).is_absolute() {
FsPathInner::Absolute(path) FsPathInner::Absolute(path)
} else if fd >= 0 { } else if fd >= 0 {
@ -83,6 +86,9 @@ impl<'a> FsPath<'a> {
fs.cwd().to_owned() fs.cwd().to_owned()
} }
}; };
if abs_path.len() > PATH_MAX {
return_errno!(ENAMETOOLONG, "abs path too long");
}
Ok(abs_path) Ok(abs_path)
} }
} }

@ -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 new(name: &str, ino: u64, type_: FileType) -> Self;
fn rec_len(&self) -> usize; fn rec_len(&self) -> usize;
fn dump(&self, buf: &mut [u8], name: &str, type_: FileType) -> Result<()>; fn dump(&self, buf: &mut [u8], name: &str, type_: FileType) -> Result<()>;

@ -12,8 +12,6 @@ use super::*;
use config::ConfigMountFsType; use config::ConfigMountFsType;
use util::mem_util::from_user; use util::mem_util::from_user;
pub const MAX_PATH_LEN: usize = 255;
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub struct iovec_t { pub struct iovec_t {
base: *const c_void, base: *const c_void,
@ -115,11 +113,6 @@ pub fn do_openat(dirfd: i32, path: *const i8, flags: u32, mode: u16) -> Result<i
let path = from_user::clone_cstring_safely(path)? let path = from_user::clone_cstring_safely(path)?
.to_string_lossy() .to_string_lossy()
.into_owned(); .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 fs_path = FsPath::new(&path, dirfd, false)?;
let mode = FileMode::from_bits_truncate(mode); let mode = FileMode::from_bits_truncate(mode);
let fd = file_ops::do_openat(&fs_path, flags, mode)?; let fd = file_ops::do_openat(&fs_path, flags, mode)?;
@ -382,7 +375,7 @@ pub fn do_chdir(path: *const i8) -> Result<isize> {
.into_owned(); .into_owned();
if path.is_empty() { if path.is_empty() {
return_errno!(ENOENT, "path is an empty string"); 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"); return_errno!(ENAMETOOLONG, "path name too long");
} }
fs_ops::do_chdir(&path)?; fs_ops::do_chdir(&path)?;
@ -429,11 +422,6 @@ pub fn do_renameat(
let newpath = from_user::clone_cstring_safely(newpath)? let newpath = from_user::clone_cstring_safely(newpath)?
.to_string_lossy() .to_string_lossy()
.into_owned(); .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 old_fs_path = FsPath::new(&oldpath, olddirfd, false)?;
let new_fs_path = FsPath::new(&newpath, newdirfd, false)?; let new_fs_path = FsPath::new(&newpath, newdirfd, false)?;
file_ops::do_renameat(&old_fs_path, &new_fs_path)?; 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<isize> {
let path = from_user::clone_cstring_safely(path)? let path = from_user::clone_cstring_safely(path)?
.to_string_lossy() .to_string_lossy()
.into_owned(); .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 fs_path = FsPath::new(&path, dirfd, false)?;
let mode = FileMode::from_bits_truncate(mode); let mode = FileMode::from_bits_truncate(mode);
file_ops::do_mkdirat(&fs_path, mode)?; file_ops::do_mkdirat(&fs_path, mode)?;
@ -465,7 +448,7 @@ pub fn do_rmdir(path: *const i8) -> Result<isize> {
.into_owned(); .into_owned();
if path.is_empty() { if path.is_empty() {
return_errno!(ENOENT, "path is an empty string"); 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"); return_errno!(ENAMETOOLONG, "path name too long");
} }
file_ops::do_rmdir(&path)?; file_ops::do_rmdir(&path)?;
@ -558,11 +541,6 @@ pub fn do_fchmodat(dirfd: i32, path: *const i8, mode: u16) -> Result<isize> {
let path = from_user::clone_cstring_safely(path)? let path = from_user::clone_cstring_safely(path)?
.to_string_lossy() .to_string_lossy()
.into_owned(); .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 mode = FileMode::from_bits_truncate(mode);
let fs_path = FsPath::new(&path, dirfd, false)?; let fs_path = FsPath::new(&path, dirfd, false)?;
file_ops::do_fchmodat(&fs_path, mode)?; file_ops::do_fchmodat(&fs_path, mode)?;
@ -681,6 +659,13 @@ pub fn do_statfs(path: *const i8, statfs_buf: *mut Statfs) -> Result<isize> {
let path = from_user::clone_cstring_safely(path)? let path = from_user::clone_cstring_safely(path)?
.to_string_lossy() .to_string_lossy()
.into_owned(); .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)?; let statfs = fs_ops::do_statfs(&path)?;
unsafe { unsafe {
statfs_buf.write(statfs); statfs_buf.write(statfs);
@ -701,6 +686,11 @@ pub fn do_mount(
let target = from_user::clone_cstring_safely(target)? let target = from_user::clone_cstring_safely(target)?
.to_string_lossy() .to_string_lossy()
.into_owned(); .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 flags = MountFlags::from_bits(flags).ok_or_else(|| errno!(EINVAL, "invalid flags"))?;
let mount_options = { let mount_options = {
let fs_type = { let fs_type = {

@ -139,8 +139,13 @@ impl UnixPath {
if self.inner.is_absolute() { if self.inner.is_absolute() {
path_str.to_string() path_str.to_string()
} else { } else {
let mut prefix = path_str.to_owned(); let mut prefix = self.cwd.as_ref().unwrap().clone();
prefix.push_str(self.cwd.as_ref().unwrap()); if prefix.ends_with("/") {
prefix.push_str(path_str);
} else {
prefix.push_str("/");
prefix.push_str(path_str);
}
prefix prefix
} }
} }