Skip to content

Commit 105ca48

Browse files
Add support for setxattr and listxattr system calls with proper argument conversions
1 parent ae63bbe commit 105ca48

5 files changed

Lines changed: 62 additions & 25 deletions

File tree

src/glibc/lind_syscall/lind_syscall_num.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@
109109
#define STATFS_SYSCALL 137
110110
#define FSTATFS_SYSCALL 138
111111
#define GETHOSTNAME_SYSCALL 170
112+
#define SETXATTR_SYSCALL 188
113+
#define LISTXATTR_SYSCALL 194
112114
#define FUTEX_SYSCALL 202
113115
#define EPOLL_CREATE_SYSCALL 213
114116
#define CLOCK_GETTIME_SYSCALL 228
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <sys/xattr.h>
2+
#include <errno.h>
3+
#include <syscall-template.h>
4+
#include <lind_syscall_num.h>
5+
#include <addr_translation.h>
6+
7+
/* List extended attributes associated with the file specified by path.
8+
If list is NULL and size is zero, returns the buffer size needed.
9+
Returns the size of the attribute list, or -1 and sets errno on error. */
10+
ssize_t
11+
__listxattr (const char *path, char *list, size_t size)
12+
{
13+
return MAKE_LEGACY_SYSCALL (LISTXATTR_SYSCALL, "syscall|listxattr",
14+
(uint64_t) TRANSLATE_GUEST_POINTER_TO_HOST (path),
15+
(uint64_t) TRANSLATE_GUEST_POINTER_TO_HOST (list),
16+
(uint64_t) size,
17+
NOTUSED,
18+
NOTUSED,
19+
NOTUSED, TRANSLATE_ERRNO_ON);
20+
}
21+
weak_alias(__listxattr, listxattr)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <sys/xattr.h>
2+
#include <errno.h>
3+
#include <syscall-template.h>
4+
#include <lind_syscall_num.h>
5+
#include <addr_translation.h>
6+
7+
/* Set extended attributes on a file specified by path.
8+
Returns 0 on success, or -1 and sets errno on error. */
9+
int
10+
__setxattr (const char *path, const char *name, const void *value,
11+
size_t size, int flags)
12+
{
13+
return MAKE_LEGACY_SYSCALL (SETXATTR_SYSCALL, "syscall|setxattr",
14+
(uint64_t) TRANSLATE_GUEST_POINTER_TO_HOST (path),
15+
(uint64_t) TRANSLATE_GUEST_POINTER_TO_HOST (name),
16+
(uint64_t) TRANSLATE_GUEST_POINTER_TO_HOST (value),
17+
(uint64_t) size,
18+
(uint64_t) flags,
19+
NOTUSED, TRANSLATE_ERRNO_ON);
20+
}
21+
weak_alias(__setxattr, setxattr)

src/rawposix/src/fs_calls.rs

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4803,20 +4803,6 @@ pub extern "C" fn symlinkat_syscall(
48034803

48044804
ret
48054805
}
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-
}
48204806

48214807
/// Linux reference: https://man7.org/linux/man-pages/man2/setxattr.2.html
48224808
///
@@ -4853,18 +4839,24 @@ pub extern "C" fn setxattr_syscall(
48534839
arg6: u64,
48544840
arg6_cageid: u64,
48554841
) -> i32 {
4856-
// Type conversion
4842+
// Type conversion for path
48574843
let path = match sc_convert_path_to_host(path_arg, path_cageid, cageid) {
48584844
Ok(path) => path,
48594845
Err(e) => return syscall_error(e, "setxattr", "path conversion failed"),
48604846
};
48614847

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"),
4848+
// Type conversion for name (attribute name, not a path - no path normalization needed)
4849+
let name_str = match get_cstr(name_arg) {
4850+
Ok(s) => s,
4851+
Err(_) => return syscall_error(Errno::EFAULT, "setxattr", "name conversion failed"),
4852+
};
4853+
let name = match std::ffi::CString::new(name_str) {
4854+
Ok(s) => s,
4855+
Err(_) => return syscall_error(Errno::EINVAL, "setxattr", "name contains null byte"),
48654856
};
48664857

4867-
let value = value_arg as *const libc::c_void;
4858+
// Type conversion for value buffer
4859+
let value = sc_convert_buf(value_arg, value_cageid, cageid) as *const libc::c_void;
48684860
let size = sc_convert_sysarg_to_usize(size_arg, size_cageid, cageid);
48694861
let flags = sc_convert_sysarg_to_i32(flags_arg, flags_cageid, cageid);
48704862

@@ -4919,16 +4911,17 @@ pub extern "C" fn listxattr_syscall(
49194911
arg6: u64,
49204912
arg6_cageid: u64,
49214913
) -> i32 {
4922-
// Type conversion
4914+
// Type conversion for path
49234915
let path = match sc_convert_path_to_host(path_arg, path_cageid, cageid) {
49244916
Ok(path) => path,
49254917
Err(e) => return syscall_error(e, "listxattr", "path conversion failed"),
49264918
};
49274919

4920+
// Type conversion for list buffer (may be NULL)
49284921
let list = if list_arg == 0 {
49294922
std::ptr::null_mut()
49304923
} else {
4931-
list_arg as *mut libc::c_char
4924+
sc_convert_to_u8_mut(list_arg, list_cageid, cageid) as *mut libc::c_char
49324925
};
49334926
let size = sc_convert_sysarg_to_usize(size_arg, size_cageid, cageid);
49344927

src/rawposix/src/syscall_table.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ use super::fs_calls::{
1212
mknod_syscall, mmap_syscall, mprotect_syscall, munmap_syscall, nanosleep_time64_syscall,
1313
open_syscall, openat_syscall, pipe2_syscall, pipe_syscall, pread_syscall, preadv_syscall,
1414
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,
15+
readv_syscall, rename_syscall, rmdir_syscall, setxattr_syscall, shmat_syscall, shmctl_syscall,
16+
shmdt_syscall, shmget_syscall, stat_syscall, statfs_syscall, symlink_syscall,
17+
symlinkat_syscall, sync_file_range_syscall, truncate_syscall, unlink_syscall, unlinkat_syscall,
18+
write_syscall, writev_syscall,
1919
};
2020
use super::init::RawCallFunc;
2121
use super::net_calls::{

0 commit comments

Comments
 (0)