Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions etc/syscalls_linux_aarch64.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@
| 0x2 (2) | io_submit | (aio_context_t ctx_id, long nr, struct iocb **iocbpp) | __arm64_sys_io_submit | false |
| 0x3 (3) | io_cancel | (aio_context_t ctx_id, struct iocb *iocb, struct io_event *result) | __arm64_sys_io_cancel | false |
| 0x4 (4) | io_getevents | (aio_context_t ctx_id, long min_nr, long nr, struct io_event *events, struct __kernel_timespec *timeout) | __arm64_sys_io_getevents | false |
| 0x5 (5) | setxattr | (const char *pathname, const char *name, const void *value, size_t size, int flags) | __arm64_sys_setxattr | false |
| 0x6 (6) | lsetxattr | (const char *pathname, const char *name, const void *value, size_t size, int flags) | __arm64_sys_lsetxattr | false |
| 0x7 (7) | fsetxattr | (int fd, const char *name, const void *value, size_t size, int flags) | __arm64_sys_fsetxattr | false |
| 0x8 (8) | getxattr | (const char *pathname, const char *name, void *value, size_t size) | __arm64_sys_getxattr | false |
| 0x9 (9) | lgetxattr | (const char *pathname, const char *name, void *value, size_t size) | __arm64_sys_lgetxattr | false |
| 0xa (10) | fgetxattr | (int fd, const char *name, void *value, size_t size) | __arm64_sys_fgetxattr | false |
| 0xb (11) | listxattr | (const char *pathname, char *list, size_t size) | __arm64_sys_listxattr | false |
| 0xc (12) | llistxattr | (const char *pathname, char *list, size_t size) | __arm64_sys_llistxattr | false |
| 0xd (13) | flistxattr | (int fd, char *list, size_t size) | __arm64_sys_flistxattr | false |
| 0xe (14) | removexattr | (const char *pathname, const char *name) | __arm64_sys_removexattr | false |
| 0xf (15) | lremovexattr | (const char *pathname, const char *name) | __arm64_sys_lremovexattr | false |
| 0x10 (16) | fremovexattr | (int fd, const char *name) | __arm64_sys_fremovexattr | false |
| 0x5 (5) | setxattr | (const char *pathname, const char *name, const void *value, size_t size, int flags) | __arm64_sys_setxattr | true |
| 0x6 (6) | lsetxattr | (const char *pathname, const char *name, const void *value, size_t size, int flags) | __arm64_sys_lsetxattr | true |
| 0x7 (7) | fsetxattr | (int fd, const char *name, const void *value, size_t size, int flags) | __arm64_sys_fsetxattr | true |
| 0x8 (8) | getxattr | (const char *pathname, const char *name, void *value, size_t size) | __arm64_sys_getxattr | true |
| 0x9 (9) | lgetxattr | (const char *pathname, const char *name, void *value, size_t size) | __arm64_sys_lgetxattr | true |
| 0xa (10) | fgetxattr | (int fd, const char *name, void *value, size_t size) | __arm64_sys_fgetxattr | true |
| 0xb (11) | listxattr | (const char *pathname, char *list, size_t size) | __arm64_sys_listxattr | true |
| 0xc (12) | llistxattr | (const char *pathname, char *list, size_t size) | __arm64_sys_llistxattr | true |
| 0xd (13) | flistxattr | (int fd, char *list, size_t size) | __arm64_sys_flistxattr | true |
| 0xe (14) | removexattr | (const char *pathname, const char *name) | __arm64_sys_removexattr | true |
| 0xf (15) | lremovexattr | (const char *pathname, const char *name) | __arm64_sys_lremovexattr | true |
| 0x10 (16) | fremovexattr | (int fd, const char *name) | __arm64_sys_fremovexattr | true |
| 0x11 (17) | getcwd | (char *buf, unsigned long size) | __arm64_sys_getcwd | true |
| 0x13 (19) | eventfd2 | (unsigned int count, int flags) | __arm64_sys_eventfd2 | false |
| 0x14 (20) | epoll_create1 | (int flags) | __arm64_sys_epoll_create1 | false |
Expand Down
3 changes: 3 additions & 0 deletions libkernel/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ pub enum KernelError {
#[error("Operation timed out")]
TimedOut,

#[error("Value out of range")]
RangeError,

#[error("{0}")]
Other(&'static str),
}
Expand Down
1 change: 1 addition & 0 deletions libkernel/src/error/syscall_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub fn kern_err_to_syscall(err: KernelError) -> isize {
KernelError::NotSupported => ENOSYS,
KernelError::NoMemory => ENOMEM,
KernelError::TimedOut => ETIMEDOUT,
KernelError::RangeError => ERANGE,
e => todo!("{e}"),
}
}
1 change: 1 addition & 0 deletions libkernel/src/fs/filesystems/ext4/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::{
},
};
use alloc::string::ToString;
use alloc::vec::Vec;
use alloc::{
boxed::Box,
sync::{Arc, Weak},
Expand Down
12 changes: 12 additions & 0 deletions libkernel/src/fs/filesystems/tmpfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,7 @@ struct TmpFsSymlinkInode<C: CpuOps> {
id: InodeId,
target: PathBuf,
attr: SpinLockIrq<FileAttr, C>,
xattr: SpinLockIrq<Vec<(String, Vec<u8>)>, C>,
}

#[async_trait]
Expand All @@ -707,6 +708,16 @@ impl<C: CpuOps> Inode for TmpFsSymlinkInode<C> {
async fn readlink(&self) -> Result<PathBuf> {
Ok(self.target.clone())
}

async fn getxattr(&self, name: &str) -> Result<Vec<u8>> {
let guard = self.xattr.lock_save_irq();
for (key, value) in guard.iter() {
if key == name {
return Ok(value.clone());
}
}
Err(FsError::NotFound.into())
}
}

impl<C: CpuOps> TmpFsSymlinkInode<C> {
Expand All @@ -720,6 +731,7 @@ impl<C: CpuOps> TmpFsSymlinkInode<C> {
nlinks: 1,
..Default::default()
}),
xattr: SpinLockIrq::new(Vec::new()),
})
}
}
Expand Down
21 changes: 21 additions & 0 deletions libkernel/src/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use crate::{
error::{FsError, KernelError, Result},
fs::{path::Path, pathbuf::PathBuf},
};
use alloc::vec::Vec;
use alloc::{boxed::Box, string::String, sync::Arc};
use async_trait::async_trait;
use attr::{FileAttr, FilePermissions};
Expand Down Expand Up @@ -211,6 +212,26 @@ pub trait Inode: Send + Sync + Any {
Err(KernelError::NotSupported)
}

/// Gets an extended attribute.
async fn getxattr(&self, _name: &str) -> Result<Vec<u8>> {
Err(KernelError::NotSupported)
}

/// Sets an extended attribute.
async fn setxattr(&self, _name: &str, _buf: &[u8], _flags: i32) -> Result<()> {
Err(KernelError::NotSupported)
}

/// Removes an extended attribute.
async fn removexattr(&self, _name: &str) -> Result<()> {
Err(KernelError::NotSupported)
}

/// Lists all extended attribute names.
async fn listxattr(&self) -> Result<Vec<String>> {
Ok(Vec::new())
}

/// Looks up a name within a directory, returning the corresponding inode.
async fn lookup(&self, _name: &str) -> Result<Arc<dyn Inode>> {
Err(KernelError::NotSupported)
Expand Down
81 changes: 81 additions & 0 deletions src/arch/arm64/exceptions/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@ use crate::{
chmod::sys_fchmod,
chown::sys_fchown,
close::sys_close,
getxattr::{sys_fgetxattr, sys_getxattr, sys_lgetxattr},
ioctl::sys_ioctl,
iov::{sys_preadv, sys_preadv2, sys_pwritev, sys_pwritev2, sys_readv, sys_writev},
listxattr::{sys_flistxattr, sys_listxattr, sys_llistxattr},
removexattr::{sys_fremovexattr, sys_lremovexattr, sys_removexattr},
rw::{sys_pread64, sys_pwrite64, sys_read, sys_write},
seek::sys_lseek,
setxattr::{sys_fsetxattr, sys_lsetxattr, sys_setxattr},
splice::sys_sendfile,
stat::sys_fstat,
sync::{sys_fdatasync, sys_fsync, sys_sync, sys_syncfs},
Expand Down Expand Up @@ -97,6 +101,83 @@ pub async fn handle_syscall() {
};

let res = match nr {
0x5 => {
sys_setxattr(
TUA::from_value(arg1 as _),
TUA::from_value(arg2 as _),
TUA::from_value(arg3 as _),
arg4 as _,
arg5 as _,
)
.await
}
0x6 => {
sys_lsetxattr(
TUA::from_value(arg1 as _),
TUA::from_value(arg2 as _),
TUA::from_value(arg3 as _),
arg4 as _,
arg5 as _,
)
.await
}
0x7 => {
sys_fsetxattr(
arg1.into(),
TUA::from_value(arg2 as _),
TUA::from_value(arg3 as _),
arg4 as _,
arg5 as _,
)
.await
}
0x8 => {
sys_getxattr(
TUA::from_value(arg1 as _),
TUA::from_value(arg2 as _),
TUA::from_value(arg3 as _),
arg4 as _,
)
.await
}
0x9 => {
sys_lgetxattr(
TUA::from_value(arg1 as _),
TUA::from_value(arg2 as _),
TUA::from_value(arg3 as _),
arg4 as _,
)
.await
}
0xa => {
sys_fgetxattr(
arg1.into(),
TUA::from_value(arg2 as _),
TUA::from_value(arg3 as _),
arg4 as _,
)
.await
}
0xb => {
sys_listxattr(
TUA::from_value(arg1 as _),
TUA::from_value(arg2 as _),
arg3 as _,
)
.await
}
0xc => {
sys_llistxattr(
TUA::from_value(arg1 as _),
TUA::from_value(arg2 as _),
arg3 as _,
)
.await
}
0xd => sys_flistxattr(arg1.into(), TUA::from_value(arg2 as _), arg3 as _).await,
0xe => sys_removexattr(TUA::from_value(arg1 as _), TUA::from_value(arg2 as _)).await,
0xf => sys_lremovexattr(TUA::from_value(arg1 as _), TUA::from_value(arg2 as _)).await,
0x10 => sys_fremovexattr(arg1.into(), TUA::from_value(arg2 as _)).await,
0x11 => sys_getcwd(TUA::from_value(arg1 as _), arg2 as _).await,
0x17 => sys_dup(arg1.into()),
0x18 => sys_dup3(arg1.into(), arg2.into(), arg3 as _),
Expand Down
88 changes: 88 additions & 0 deletions src/fs/syscalls/getxattr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use crate::fs::VFS;
use crate::memory::uaccess::copy_to_user_slice;
use crate::memory::uaccess::cstr::UserCStr;
use crate::process::fd_table::Fd;
use crate::sched::current::current_task_shared;
use alloc::sync::Arc;
use core::ffi::c_char;
use libkernel::error::{KernelError, Result};
use libkernel::fs::Inode;
use libkernel::fs::path::Path;
use libkernel::memory::address::{TUA, UA};

async fn getxattr(node: Arc<dyn Inode>, name: &str, ua: UA, size: usize) -> Result<usize> {
let value = node.getxattr(name).await?;
if size < value.len() {
Err(KernelError::RangeError)
} else {
copy_to_user_slice(&value, ua).await?;
Ok(value.len())
}
}

pub async fn sys_getxattr(
path: TUA<c_char>,
name: TUA<c_char>,
value: UA,
size: usize,
) -> Result<usize> {
let mut buf = [0; 1024];

let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
let task = current_task_shared();

let node = VFS.resolve_path(path, VFS.root_inode(), &task).await?;
let mut buf = [0; 1024];
getxattr(
node,
UserCStr::from_ptr(name).copy_from_user(&mut buf).await?,
value,
size,
)
.await
}

pub async fn sys_lgetxattr(
path: TUA<c_char>,
name: TUA<c_char>,
value: UA,
size: usize,
) -> Result<usize> {
let mut buf = [0; 1024];

let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
let task = current_task_shared();

let node = VFS
.resolve_path_nofollow(path, VFS.root_inode(), &task)
.await?;
let mut buf = [0; 1024];
getxattr(
node,
UserCStr::from_ptr(name).copy_from_user(&mut buf).await?,
value,
size,
)
.await
}

pub async fn sys_fgetxattr(fd: Fd, name: TUA<c_char>, value: UA, size: usize) -> Result<usize> {
let node = {
let task = current_task_shared();
let file = task
.fd_table
.lock_save_irq()
.get(fd)
.ok_or(KernelError::BadFd)?;

file.inode().ok_or(KernelError::BadFd)?
};
let mut buf = [0; 1024];
getxattr(
node,
UserCStr::from_ptr(name).copy_from_user(&mut buf).await?,
value,
size,
)
.await
}
49 changes: 49 additions & 0 deletions src/fs/syscalls/listxattr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use crate::fs::VFS;
use crate::memory::uaccess::cstr::UserCStr;
use crate::process::fd_table::Fd;
use crate::sched::current::current_task_shared;
use alloc::sync::Arc;
use libkernel::error::{KernelError, Result};
use libkernel::fs::Inode;
use libkernel::fs::path::Path;
use libkernel::memory::address::{TUA, UA};

async fn listxattr(_node: Arc<dyn Inode>, _ua: UA, _size: usize) -> Result<usize> {
Err(KernelError::NotSupported)
}

pub async fn sys_listxattr(path: TUA<core::ffi::c_char>, list: UA, size: usize) -> Result<usize> {
let mut buf = [0; 1024];

let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
let task = current_task_shared();

let node = VFS.resolve_path(path, VFS.root_inode(), &task).await?;
listxattr(node, list, size).await
}

pub async fn sys_llistxattr(path: TUA<core::ffi::c_char>, list: UA, size: usize) -> Result<usize> {
let mut buf = [0; 1024];

let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
let task = current_task_shared();

let node = VFS
.resolve_path_nofollow(path, VFS.root_inode(), &task)
.await?;
listxattr(node, list, size).await
}

pub async fn sys_flistxattr(fd: Fd, list: UA, size: usize) -> Result<usize> {
let node = {
let task = current_task_shared();
let file = task
.fd_table
.lock_save_irq()
.get(fd)
.ok_or(KernelError::BadFd)?;

file.inode().ok_or(KernelError::BadFd)?
};
listxattr(node, list, size).await
}
4 changes: 4 additions & 0 deletions src/fs/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@ pub mod chdir;
pub mod chmod;
pub mod chown;
pub mod close;
pub mod getxattr;
pub mod ioctl;
pub mod iov;
pub mod listxattr;
pub mod open;
pub mod removexattr;
pub mod rw;
pub mod seek;
pub mod setxattr;
pub mod splice;
pub mod stat;
pub mod sync;
Expand Down
Loading
Loading