mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-09 05:16:47 +00:00
Add sys_access and sys_faccessat
This commit is contained in:
parent
212dd562a0
commit
d33f90eaeb
@ -289,7 +289,7 @@ provided by Linux on x86-64 architecture.
|
|||||||
| 266 | symlinkat | ✅ |
|
| 266 | symlinkat | ✅ |
|
||||||
| 267 | readlinkat | ✅ |
|
| 267 | readlinkat | ✅ |
|
||||||
| 268 | fchmodat | ✅ |
|
| 268 | fchmodat | ✅ |
|
||||||
| 269 | faccessat | ❌ |
|
| 269 | faccessat | ✅ |
|
||||||
| 270 | pselect6 | ❌ |
|
| 270 | pselect6 | ❌ |
|
||||||
| 271 | ppoll | ❌ |
|
| 271 | ppoll | ❌ |
|
||||||
| 272 | unshare | ❌ |
|
| 272 | unshare | ❌ |
|
||||||
|
@ -1,11 +1,96 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use super::{constants::*, SyscallReturn};
|
use super::SyscallReturn;
|
||||||
use crate::{prelude::*, util::read_cstring_from_user};
|
use crate::{
|
||||||
|
fs::{
|
||||||
|
file_table::FileDesc,
|
||||||
|
fs_resolver::{FsPath, AT_FDCWD},
|
||||||
|
utils::PATH_MAX,
|
||||||
|
},
|
||||||
|
prelude::*,
|
||||||
|
util::read_cstring_from_user,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn sys_faccessat(dirfd: FileDesc, path_ptr: Vaddr, mode: u16) -> Result<SyscallReturn> {
|
||||||
|
debug!(
|
||||||
|
"faccessat: dirfd = {}, path_ptr = {:#x}, mode = {:o}",
|
||||||
|
dirfd, path_ptr, mode
|
||||||
|
);
|
||||||
|
|
||||||
|
do_faccessat(dirfd, path_ptr, mode, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sys_access(path_ptr: Vaddr, mode: u16) -> Result<SyscallReturn> {
|
||||||
|
debug!("access: path_ptr = {:#x}, mode = {:o}", path_ptr, mode);
|
||||||
|
|
||||||
|
do_faccessat(AT_FDCWD, path_ptr, mode, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
struct FaccessatFlags: i32 {
|
||||||
|
const AT_EACCESS = 0x200;
|
||||||
|
const AT_SYMLINK_NOFOLLOW = 0x100;
|
||||||
|
const AT_EMPTY_PATH = 0x1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
struct AccessMode: u16 {
|
||||||
|
const R_OK = 0x4;
|
||||||
|
const W_OK = 0x2;
|
||||||
|
const X_OK = 0x1;
|
||||||
|
// We could ignore F_OK in bitflags.
|
||||||
|
// const F_OK = 0x0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn do_faccessat(
|
||||||
|
dirfd: FileDesc,
|
||||||
|
path_ptr: Vaddr,
|
||||||
|
mode: u16,
|
||||||
|
flags: i32,
|
||||||
|
) -> Result<SyscallReturn> {
|
||||||
|
let mode = AccessMode::from_bits(mode)
|
||||||
|
.ok_or_else(|| Error::with_message(Errno::EINVAL, "Invalid mode"))?;
|
||||||
|
let flags = FaccessatFlags::from_bits(flags)
|
||||||
|
.ok_or_else(|| Error::with_message(Errno::EINVAL, "Invalid flags"))?;
|
||||||
|
|
||||||
|
let path = read_cstring_from_user(path_ptr, PATH_MAX)?;
|
||||||
|
debug!(
|
||||||
|
"dirfd = {}, path = {:?}, mode = {:o}, flags = {:?}",
|
||||||
|
dirfd, path, mode, flags
|
||||||
|
);
|
||||||
|
|
||||||
|
let current = current!();
|
||||||
|
let dentry = {
|
||||||
|
let path = path.to_string_lossy();
|
||||||
|
let fs_path = FsPath::new(dirfd, path.as_ref())?;
|
||||||
|
let fs = current.fs().read();
|
||||||
|
if flags.contains(FaccessatFlags::AT_SYMLINK_NOFOLLOW) {
|
||||||
|
fs.lookup_no_follow(&fs_path)?
|
||||||
|
} else {
|
||||||
|
fs.lookup(&fs_path)?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// AccessMode::empty() means F_OK and no more permission check needed.
|
||||||
|
if mode.is_empty() {
|
||||||
|
return Ok(SyscallReturn::Return(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
let inode_mode = dentry.mode()?;
|
||||||
|
|
||||||
|
// FIXME: The current implementation is dummy
|
||||||
|
if mode.contains(AccessMode::R_OK) && !inode_mode.is_readable() {
|
||||||
|
return_errno_with_message!(Errno::EACCES, "Read permission denied");
|
||||||
|
}
|
||||||
|
|
||||||
|
if mode.contains(AccessMode::W_OK) && !inode_mode.is_writable() {
|
||||||
|
return_errno_with_message!(Errno::EACCES, "Write permission denied");
|
||||||
|
}
|
||||||
|
|
||||||
|
if mode.contains(AccessMode::X_OK) && !inode_mode.is_executable() {
|
||||||
|
return_errno_with_message!(Errno::EACCES, "Execute permission denied");
|
||||||
|
}
|
||||||
|
|
||||||
pub fn sys_access(filename_ptr: Vaddr, file_mode: u64) -> Result<SyscallReturn> {
|
|
||||||
let filename = read_cstring_from_user(filename_ptr, MAX_FILENAME_LEN)?;
|
|
||||||
debug!("filename: {:?}, file_mode = {}", filename, file_mode);
|
|
||||||
// TODO: access currenly does not check and just return success
|
|
||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use crate::syscall::{
|
use crate::syscall::{
|
||||||
accept::{sys_accept, sys_accept4},
|
accept::{sys_accept, sys_accept4},
|
||||||
access::sys_access,
|
access::{sys_access, sys_faccessat},
|
||||||
alarm::sys_alarm,
|
alarm::sys_alarm,
|
||||||
arch_prctl::sys_arch_prctl,
|
arch_prctl::sys_arch_prctl,
|
||||||
bind::sys_bind,
|
bind::sys_bind,
|
||||||
@ -272,6 +272,7 @@ impl_syscall_nums_and_dispatch_fn! {
|
|||||||
SYS_SYMLINKAT = 266 => sys_symlinkat(args[..3]);
|
SYS_SYMLINKAT = 266 => sys_symlinkat(args[..3]);
|
||||||
SYS_READLINKAT = 267 => sys_readlinkat(args[..4]);
|
SYS_READLINKAT = 267 => sys_readlinkat(args[..4]);
|
||||||
SYS_FCHMODAT = 268 => sys_fchmodat(args[..3]);
|
SYS_FCHMODAT = 268 => sys_fchmodat(args[..3]);
|
||||||
|
SYS_FACCESSAT = 269 => sys_faccessat(args[..3]);
|
||||||
SYS_SET_ROBUST_LIST = 273 => sys_set_robust_list(args[..2]);
|
SYS_SET_ROBUST_LIST = 273 => sys_set_robust_list(args[..2]);
|
||||||
SYS_UTIMENSAT = 280 => sys_utimensat(args[..4]);
|
SYS_UTIMENSAT = 280 => sys_utimensat(args[..4]);
|
||||||
SYS_EPOLL_PWAIT = 281 => sys_epoll_pwait(args[..6]);
|
SYS_EPOLL_PWAIT = 281 => sys_epoll_pwait(args[..6]);
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#
|
#
|
||||||
# Please keep the list sorted by name.
|
# Please keep the list sorted by name.
|
||||||
TESTS ?= \
|
TESTS ?= \
|
||||||
|
access_test \
|
||||||
alarm_test \
|
alarm_test \
|
||||||
chmod_test \
|
chmod_test \
|
||||||
chown_test \
|
chown_test \
|
||||||
|
1
regression/syscall_test/blocklists.exfat/access_test
Normal file
1
regression/syscall_test/blocklists.exfat/access_test
Normal file
@ -0,0 +1 @@
|
|||||||
|
AccessTest.UsrReadWrite
|
3
regression/syscall_test/blocklists/access_test
Normal file
3
regression/syscall_test/blocklists/access_test
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
AccessTest.NoPerms
|
||||||
|
AccessTest.UsrReadOnly
|
||||||
|
AccessTest.UsrReadExec
|
Loading…
x
Reference in New Issue
Block a user