mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-08 21:06:48 +00:00
108 lines
2.8 KiB
Rust
108 lines
2.8 KiB
Rust
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
use super::{
|
|
setxattr::{lookup_dentry_for_xattr, XattrFileCtx},
|
|
SyscallReturn,
|
|
};
|
|
use crate::{
|
|
fs::{
|
|
file_table::{get_file_fast, FileDesc},
|
|
utils::{XattrNamespace, XATTR_LIST_MAX_LEN},
|
|
},
|
|
prelude::*,
|
|
process::credentials::capabilities::CapSet,
|
|
syscall::constants::MAX_FILENAME_LEN,
|
|
};
|
|
|
|
pub fn sys_listxattr(
|
|
path_ptr: Vaddr,
|
|
list_ptr: Vaddr, // The given list is used to place xattr (null-terminated) names.
|
|
list_len: usize,
|
|
ctx: &Context,
|
|
) -> Result<SyscallReturn> {
|
|
let user_space = ctx.user_space();
|
|
let path = user_space.read_cstring(path_ptr, MAX_FILENAME_LEN)?;
|
|
|
|
let len = listxattr(
|
|
XattrFileCtx::Path(path),
|
|
list_ptr,
|
|
list_len,
|
|
&user_space,
|
|
ctx,
|
|
)?;
|
|
|
|
Ok(SyscallReturn::Return(len as _))
|
|
}
|
|
|
|
pub fn sys_llistxattr(
|
|
path_ptr: Vaddr,
|
|
list_ptr: Vaddr, // The given list is used to place xattr (null-terminated) names.
|
|
list_len: usize,
|
|
ctx: &Context,
|
|
) -> Result<SyscallReturn> {
|
|
let user_space = ctx.user_space();
|
|
let path = user_space.read_cstring(path_ptr, MAX_FILENAME_LEN)?;
|
|
|
|
let len = listxattr(
|
|
XattrFileCtx::PathNoFollow(path),
|
|
list_ptr,
|
|
list_len,
|
|
&user_space,
|
|
ctx,
|
|
)?;
|
|
|
|
Ok(SyscallReturn::Return(len as _))
|
|
}
|
|
|
|
pub fn sys_flistxattr(
|
|
fd: FileDesc,
|
|
list_ptr: Vaddr, // The given list is used to place xattr (null-terminated) names.
|
|
list_len: usize,
|
|
ctx: &Context,
|
|
) -> Result<SyscallReturn> {
|
|
let mut file_table = ctx.thread_local.file_table().borrow_mut();
|
|
let file = get_file_fast!(&mut file_table, fd);
|
|
|
|
let user_space = ctx.user_space();
|
|
let len = listxattr(
|
|
XattrFileCtx::FileHandle(file),
|
|
list_ptr,
|
|
list_len,
|
|
&user_space,
|
|
ctx,
|
|
)?;
|
|
|
|
Ok(SyscallReturn::Return(len as _))
|
|
}
|
|
|
|
fn listxattr(
|
|
file_ctx: XattrFileCtx,
|
|
list_ptr: Vaddr,
|
|
list_len: usize,
|
|
user_space: &CurrentUserSpace,
|
|
ctx: &Context,
|
|
) -> Result<usize> {
|
|
if list_len > XATTR_LIST_MAX_LEN {
|
|
return_errno_with_message!(Errno::E2BIG, "xattr list too long");
|
|
}
|
|
|
|
let namespace = get_current_xattr_namespace(ctx);
|
|
let mut list_writer = user_space.writer(list_ptr, list_len)?;
|
|
|
|
let dentry = lookup_dentry_for_xattr(&file_ctx, ctx)?;
|
|
dentry.list_xattr(namespace, &mut list_writer)
|
|
}
|
|
|
|
fn get_current_xattr_namespace(ctx: &Context) -> XattrNamespace {
|
|
let credentials = ctx.posix_thread.credentials();
|
|
let permitted_capset = credentials.permitted_capset();
|
|
let effective_capset = credentials.effective_capset();
|
|
|
|
if permitted_capset.contains(CapSet::SYS_ADMIN) && effective_capset.contains(CapSet::SYS_ADMIN)
|
|
{
|
|
XattrNamespace::Trusted
|
|
} else {
|
|
XattrNamespace::User
|
|
}
|
|
}
|