From 686ec343b2407f96dc5765693630d5ba2262f644 Mon Sep 17 00:00:00 2001 From: LI Qing Date: Wed, 17 Jun 2020 13:32:06 +0800 Subject: [PATCH] Fix the dirfd issue when path is absolute --- src/libos/src/fs/file_ops/access.rs | 4 ---- src/libos/src/fs/file_ops/open.rs | 4 ---- src/libos/src/fs/file_ops/stat.rs | 4 ---- src/libos/src/fs/syscalls.rs | 21 ++++++++++++++++++--- test/access/main.c | 3 +++ test/open/main.c | 6 ++++++ test/stat/main.c | 8 +++++--- 7 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/libos/src/fs/file_ops/access.rs b/src/libos/src/fs/file_ops/access.rs index 0473be30..0a28759d 100644 --- a/src/libos/src/fs/file_ops/access.rs +++ b/src/libos/src/fs/file_ops/access.rs @@ -47,10 +47,6 @@ pub fn do_faccessat( "faccessat: dirfd: {:?}, path: {:?}, mode: {:?}, flags: {:?}", dirfd, path, mode, flags ); - if Path::new(path).is_absolute() { - // Path is absolute, so dirfd is ignored - return Ok(do_access(path, mode, flags)?); - } let path = match dirfd { DirFd::Fd(dirfd) => { let dir_path = get_dir_path(dirfd)?; diff --git a/src/libos/src/fs/file_ops/open.rs b/src/libos/src/fs/file_ops/open.rs index 432c1b53..73bf0795 100644 --- a/src/libos/src/fs/file_ops/open.rs +++ b/src/libos/src/fs/file_ops/open.rs @@ -19,10 +19,6 @@ pub fn do_openat(dirfd: DirFd, path: &str, flags: u32, mode: u32) -> Result { let dir_path = get_dir_path(dirfd)?; diff --git a/src/libos/src/fs/file_ops/stat.rs b/src/libos/src/fs/file_ops/stat.rs index af4010df..2f5abc49 100644 --- a/src/libos/src/fs/file_ops/stat.rs +++ b/src/libos/src/fs/file_ops/stat.rs @@ -171,10 +171,6 @@ pub fn do_fstatat(dirfd: DirFd, path: &str, flags: StatFlags) -> Result { if path.len() == 0 && !flags.contains(StatFlags::AT_EMPTY_PATH) { return_errno!(ENOENT, "path is an empty string"); } - if Path::new(path).is_absolute() { - // Path is absolute, so dirfd is ignored - return Ok(do_stat(path)?); - } match dirfd { DirFd::Fd(dirfd) => { if path.len() == 0 { diff --git a/src/libos/src/fs/syscalls.rs b/src/libos/src/fs/syscalls.rs index 29135ccd..ab694114 100644 --- a/src/libos/src/fs/syscalls.rs +++ b/src/libos/src/fs/syscalls.rs @@ -43,10 +43,15 @@ pub fn do_open(path: *const i8, flags: u32, mode: u32) -> Result { } pub fn do_openat(dirfd: i32, path: *const i8, flags: u32, mode: u32) -> Result { - let dirfd = DirFd::from_i32(dirfd)?; let path = from_user::clone_cstring_safely(path)? .to_string_lossy() .into_owned(); + let dirfd = if Path::new(&path).is_absolute() { + // Path is absolute, dirfd is treated as Cwd + DirFd::Cwd + } else { + DirFd::from_i32(dirfd)? + }; let fd = file_ops::do_openat(dirfd, &path, flags, mode)?; Ok(fd as isize) } @@ -179,10 +184,15 @@ pub fn do_lstat(path: *const i8, stat_buf: *mut Stat) -> Result { } pub fn do_fstatat(dirfd: i32, path: *const i8, stat_buf: *mut Stat, flags: u32) -> Result { - let dirfd = DirFd::from_i32(dirfd)?; let path = from_user::clone_cstring_safely(path)? .to_string_lossy() .into_owned(); + let dirfd = if Path::new(&path).is_absolute() { + // Path is absolute, dirfd is treated as Cwd + DirFd::Cwd + } else { + DirFd::from_i32(dirfd)? + }; from_user::check_mut_ptr(stat_buf)?; let flags = StatFlags::from_bits_truncate(flags); let stat = file_ops::do_fstatat(dirfd, &path, flags)?; @@ -202,10 +212,15 @@ pub fn do_access(path: *const i8, mode: u32) -> Result { } pub fn do_faccessat(dirfd: i32, path: *const i8, mode: u32, flags: u32) -> Result { - let dirfd = DirFd::from_i32(dirfd)?; let path = from_user::clone_cstring_safely(path)? .to_string_lossy() .into_owned(); + let dirfd = if Path::new(&path).is_absolute() { + // Path is absolute, dirfd is treated as Cwd + DirFd::Cwd + } else { + DirFd::from_i32(dirfd)? + }; let mode = AccessibilityCheckMode::from_u32(mode)?; let flags = AccessibilityCheckFlags::from_u32(flags)?; file_ops::do_faccessat(dirfd, &path, mode, flags).map(|_| 0) diff --git a/test/access/main.c b/test/access/main.c index c9a94b7e..b76139c8 100644 --- a/test/access/main.c +++ b/test/access/main.c @@ -62,6 +62,9 @@ static int __test_faccessat_with_abs_path(const char *file_path) { if (faccessat(AT_FDCWD, file_path, F_OK, 0) < 0) { THROW_ERROR("failed to faccessat file with abs path"); } + if (faccessat(-1, file_path, F_OK, 0) < 0) { + THROW_ERROR("failed to faccessat file with abs path and invalid dirfd"); + } if (remove_file(file_path) < 0) { return -1; } diff --git a/test/open/main.c b/test/open/main.c index de7e7449..30443b54 100644 --- a/test/open/main.c +++ b/test/open/main.c @@ -37,6 +37,12 @@ static int __test_openat_with_abs_path(const char *file_path, int flags, int mod THROW_ERROR("failed to openat a file with abs path"); } close(fd); + + fd = openat(-1, file_path, flags, mode); + if (fd < 0) { + THROW_ERROR("failed to openat a file with abs path and invalid dirfd"); + } + close(fd); return 0; } diff --git a/test/stat/main.c b/test/stat/main.c index d7145a00..caa42f9b 100644 --- a/test/stat/main.c +++ b/test/stat/main.c @@ -79,12 +79,14 @@ static int __test_lstat(const char *file_path) { static int __test_fstatat_with_abs_path(const char *file_path) { struct stat stat_buf; - int ret; - ret = fstatat(AT_FDCWD, file_path, &stat_buf, 0); - if (ret < 0) { + if (fstatat(AT_FDCWD, file_path, &stat_buf, 0) < 0) { THROW_ERROR("failed to fstatat file with abs path"); } + + if (fstatat(-1, file_path, &stat_buf, 0) < 0) { + THROW_ERROR("failed to fstatat file with abs path and invalid dirfd"); + } return 0; }