Fix the dirfd issue when path is absolute

This commit is contained in:
LI Qing 2020-06-17 13:32:06 +08:00
parent 1ad8f22170
commit 686ec343b2
7 changed files with 32 additions and 18 deletions

@ -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)?;

@ -19,10 +19,6 @@ pub fn do_openat(dirfd: DirFd, path: &str, flags: u32, mode: u32) -> Result<File
"openat: dirfd: {:?}, path: {:?}, flags: {:#o}, mode: {:#o}",
dirfd, path, flags, mode
);
if Path::new(path).is_absolute() {
// Path is absolute, so dirfd is ignored
return Ok(do_open(path, flags, mode)?);
}
let path = match dirfd {
DirFd::Fd(dirfd) => {
let dir_path = get_dir_path(dirfd)?;

@ -171,10 +171,6 @@ pub fn do_fstatat(dirfd: DirFd, path: &str, flags: StatFlags) -> Result<Stat> {
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 {

@ -43,10 +43,15 @@ pub fn do_open(path: *const i8, flags: u32, mode: u32) -> Result<isize> {
}
pub fn do_openat(dirfd: i32, path: *const i8, flags: u32, mode: u32) -> Result<isize> {
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<isize> {
}
pub fn do_fstatat(dirfd: i32, path: *const i8, stat_buf: *mut Stat, flags: u32) -> Result<isize> {
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<isize> {
}
pub fn do_faccessat(dirfd: i32, path: *const i8, mode: u32, flags: u32) -> Result<isize> {
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)

@ -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;
}

@ -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;
}

@ -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;
}