Skip to content

Commit ae63bbe

Browse files
Add support for setxattr and listxattr system calls
1 parent 63127df commit ae63bbe

2 files changed

Lines changed: 161 additions & 7 deletions

File tree

‎src/rawposix/src/fs_calls.rs‎

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4802,4 +4802,155 @@ pub extern "C" fn symlinkat_syscall(
48024802
}
48034803

48044804
ret
4805+
}
4806+
"getrandom_syscall"
4807+
);
4808+
}
4809+
4810+
let ret = unsafe { getrandom(buf as *mut c_void, buflen.try_into().unwrap(), flags) };
4811+
if ret < 0 {
4812+
let errno = get_errno();
4813+
return handle_errno(errno, "getrandom");
4814+
}
4815+
4816+
// convert isize to i32 safely, as ret shouldn't be larger than 32-bit
4817+
// due to buflen being u32
4818+
ret.try_into().unwrap()
4819+
}
4820+
4821+
/// Linux reference: https://man7.org/linux/man-pages/man2/setxattr.2.html
4822+
///
4823+
/// Sets the value of an extended attribute identified by `name`
4824+
/// and associated with the given `path` in the filesystem.
4825+
///
4826+
/// ## Arguments:
4827+
/// * `cageid` - Cage identifier
4828+
/// * `path_arg` - Path to the file
4829+
/// * `path_cageid` - Cage ID for path
4830+
/// * `name_arg` - Name of the extended attribute
4831+
/// * `name_cageid` - Cage ID for name
4832+
/// * `value_arg` - Pointer to the value to set
4833+
/// * `value_cageid` - Cage ID for value
4834+
/// * `size_arg` - Size of the value
4835+
/// * `size_cageid` - Cage ID for size
4836+
/// * `flags_arg` - Flags for setxattr (e.g., XATTR_CREATE, XATTR_REPLACE)
4837+
/// * `flags_cageid` - Cage ID for flags
4838+
///
4839+
/// ## Returns:
4840+
/// On success, 0 is returned. On error, -1 is returned and errno is set appropriately.
4841+
pub extern "C" fn setxattr_syscall(
4842+
cageid: u64,
4843+
path_arg: u64,
4844+
path_cageid: u64,
4845+
name_arg: u64,
4846+
name_cageid: u64,
4847+
value_arg: u64,
4848+
value_cageid: u64,
4849+
size_arg: u64,
4850+
size_cageid: u64,
4851+
flags_arg: u64,
4852+
flags_cageid: u64,
4853+
arg6: u64,
4854+
arg6_cageid: u64,
4855+
) -> i32 {
4856+
// Type conversion
4857+
let path = match sc_convert_path_to_host(path_arg, path_cageid, cageid) {
4858+
Ok(path) => path,
4859+
Err(e) => return syscall_error(e, "setxattr", "path conversion failed"),
4860+
};
4861+
4862+
let name = match sc_convert_path_to_host(name_arg, name_cageid, cageid) {
4863+
Ok(name) => name,
4864+
Err(e) => return syscall_error(e, "setxattr", "name conversion failed"),
4865+
};
4866+
4867+
let value = value_arg as *const libc::c_void;
4868+
let size = sc_convert_sysarg_to_usize(size_arg, size_cageid, cageid);
4869+
let flags = sc_convert_sysarg_to_i32(flags_arg, flags_cageid, cageid);
4870+
4871+
// Validate unused arg
4872+
if !sc_unusedarg(arg6, arg6_cageid) {
4873+
panic!(
4874+
"{}: unused arguments contain unexpected values -- security violation",
4875+
"setxattr_syscall"
4876+
);
4877+
}
4878+
4879+
// Call to kernel setxattr
4880+
let ret = unsafe { libc::setxattr(path.as_ptr(), name.as_ptr(), value, size, flags) };
4881+
4882+
if ret < 0 {
4883+
let errno = get_errno();
4884+
return handle_errno(errno, "setxattr");
4885+
}
4886+
4887+
ret
4888+
}
4889+
4890+
/// Linux reference: https://man7.org/linux/man-pages/man2/listxattr.2.html
4891+
///
4892+
/// Retrieves the list of extended attribute names associated with the given `path`.
4893+
///
4894+
/// ## Arguments:
4895+
/// * `cageid` - Cage identifier
4896+
/// * `path_arg` - Path to the file
4897+
/// * `path_cageid` - Cage ID for path
4898+
/// * `list_arg` - Pointer to buffer to store the list of attribute names
4899+
/// * `list_cageid` - Cage ID for list
4900+
/// * `size_arg` - Size of the buffer
4901+
/// * `size_cageid` - Cage ID for size
4902+
///
4903+
/// ## Returns:
4904+
/// On success, returns the size of the list of attribute names. If `list` is NULL and `size` is zero,
4905+
/// returns the size of the buffer needed to store the list.
4906+
/// On error, -1 is returned and errno is set appropriately.
4907+
pub extern "C" fn listxattr_syscall(
4908+
cageid: u64,
4909+
path_arg: u64,
4910+
path_cageid: u64,
4911+
list_arg: u64,
4912+
list_cageid: u64,
4913+
size_arg: u64,
4914+
size_cageid: u64,
4915+
arg4: u64,
4916+
arg4_cageid: u64,
4917+
arg5: u64,
4918+
arg5_cageid: u64,
4919+
arg6: u64,
4920+
arg6_cageid: u64,
4921+
) -> i32 {
4922+
// Type conversion
4923+
let path = match sc_convert_path_to_host(path_arg, path_cageid, cageid) {
4924+
Ok(path) => path,
4925+
Err(e) => return syscall_error(e, "listxattr", "path conversion failed"),
4926+
};
4927+
4928+
let list = if list_arg == 0 {
4929+
std::ptr::null_mut()
4930+
} else {
4931+
list_arg as *mut libc::c_char
4932+
};
4933+
let size = sc_convert_sysarg_to_usize(size_arg, size_cageid, cageid);
4934+
4935+
// Validate unused args
4936+
if !(sc_unusedarg(arg4, arg4_cageid)
4937+
&& sc_unusedarg(arg5, arg5_cageid)
4938+
&& sc_unusedarg(arg6, arg6_cageid))
4939+
{
4940+
panic!(
4941+
"{}: unused arguments contain unexpected values -- security violation",
4942+
"listxattr_syscall"
4943+
);
4944+
}
4945+
4946+
// Call to kernel listxattr
4947+
let ret = unsafe { libc::listxattr(path.as_ptr(), list, size) };
4948+
4949+
if ret < 0 {
4950+
let errno = get_errno();
4951+
return handle_errno(errno, "listxattr");
4952+
}
4953+
4954+
// Convert ssize_t to i32 safely
4955+
ret.try_into().unwrap_or(i32::MAX)
48054956
}

‎src/rawposix/src/syscall_table.rs‎

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ use super::fs_calls::{
88
close_syscall, dup2_syscall, dup3_syscall, dup_syscall, fchdir_syscall, fchmod_syscall,
99
fcntl_syscall, fdatasync_syscall, flock_syscall, fstat_syscall, fstatfs_syscall, fsync_syscall,
1010
ftruncate_syscall, futex_syscall, getcwd_syscall, getdents_syscall, getrandom_syscall,
11-
ioctl_syscall, link_syscall, lseek_syscall, lstat_syscall, mkdir_syscall, mknod_syscall,
12-
mmap_syscall, mprotect_syscall, munmap_syscall, nanosleep_time64_syscall, open_syscall,
13-
openat_syscall, pipe2_syscall, pipe_syscall, pread_syscall, preadv_syscall, pwrite_syscall,
14-
pwritev_syscall, read_syscall, readlink_syscall, readlinkat_syscall, readv_syscall,
15-
rename_syscall, rmdir_syscall, shmat_syscall, shmctl_syscall, shmdt_syscall, shmget_syscall,
16-
stat_syscall, statfs_syscall, symlink_syscall, symlinkat_syscall, sync_file_range_syscall,
17-
truncate_syscall, unlink_syscall, unlinkat_syscall, write_syscall, writev_syscall,
11+
ioctl_syscall, link_syscall, listxattr_syscall, lseek_syscall, lstat_syscall, mkdir_syscall,
12+
mknod_syscall, mmap_syscall, mprotect_syscall, munmap_syscall, nanosleep_time64_syscall,
13+
open_syscall, openat_syscall, pipe2_syscall, pipe_syscall, pread_syscall, preadv_syscall,
14+
pwrite_syscall, pwritev_syscall, read_syscall, readlink_syscall, readlinkat_syscall,
15+
readv_syscall, rename_syscall, rmdir_syscall, setxattr_syscall, shmat_syscall,
16+
shmctl_syscall, shmdt_syscall, shmget_syscall, stat_syscall, statfs_syscall,
17+
symlink_syscall, symlinkat_syscall, sync_file_range_syscall, truncate_syscall,
18+
unlink_syscall, unlinkat_syscall, write_syscall, writev_syscall,
1819
};
1920
use super::init::RawCallFunc;
2021
use super::net_calls::{
@@ -133,6 +134,8 @@ pub const SYSCALL_TABLE: &[(u64, RawCallFunc)] = &[
133134
syscall_const::GETHOSTNAME_SYSCALL as u64,
134135
gethostname_syscall,
135136
),
137+
(188 as u64, setxattr_syscall),
138+
(194 as u64, listxattr_syscall),
136139
(syscall_const::FUTEX_SYSCALL as u64, futex_syscall),
137140
(
138141
syscall_const::EPOLL_CREATE_SYSCALL as u64,

0 commit comments

Comments
 (0)