mirror of
https://gitlab.com/qemu-project/qemu.git
synced 2026-08-26 22:23:12 -04:00
linux-user: implement fsmount(2) series of syscalls
This series of syscalls replaces the old mount(2) syscall with a series of syscalls that operates around a filesystem context. This series of syscalls is available since Linux 5.2 and glibc 2.36+. Their users include systemd since v259 and libmount from util-linux, and possibly other widely used projects. Preliminary checks are implemented to ensure the validity of the interface. v2: Add syscall wrappers in case the build machine does not support the fsmount() syscalls. (added by Helge Deller) Signed-off-by: Xinhui Yang <cyan@cyano.uk> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Signed-off-by: Helge Deller <deller@gmx.de>
This commit is contained in:
parent
29c042c6e9
commit
767c32fe69
1 changed files with 104 additions and 0 deletions
|
|
@ -9713,6 +9713,19 @@ _syscall5(int, sys_move_mount, int, __from_dfd, const char *, __from_pathname,
|
|||
int, __to_dfd, const char *, __to_pathname, unsigned int, flag)
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_NR_fsopen) && defined(NR_fsopen)
|
||||
#define __NR_sys_fsopen __NR_fsopen
|
||||
_syscall2(int, sys_fsopen, const char *, fs_name, unsigned int, flags);
|
||||
#define __NR_sys_fsconfig __NR_fsconfig
|
||||
_syscall5(int, sys_fsconfig, int, fs_fd, unsigned int, cmd, const char *, key,
|
||||
const void *, value, int, aux)
|
||||
#define __NR_sys_fsmount __NR_fsmount
|
||||
_syscall3(int, sys_fsmount, int, fs_fd, unsigned int, flags,
|
||||
unsigned int, ms_flags)
|
||||
#define __NR_sys_fspick __NR_fspick
|
||||
_syscall3(int, sys_fspick, int, dfd, const char *, path, unsigned int, flags)
|
||||
#endif
|
||||
|
||||
/* This is an internal helper for do_syscall so that it is easier
|
||||
* to have a single return point, so that actions, such as logging
|
||||
* of syscall results, can be performed.
|
||||
|
|
@ -14412,6 +14425,97 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
|
|||
return do_map_shadow_stack(cpu_env, arg1, arg2, arg3);
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_NR_fsopen) && defined(NR_fsopen)
|
||||
case TARGET_NR_fsopen:
|
||||
{
|
||||
p = lock_user_string(arg1);
|
||||
if (!p) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
ret = get_errno(sys_fsopen(p, arg2));
|
||||
unlock_user(p, arg1, 0);
|
||||
}
|
||||
return ret;
|
||||
case TARGET_NR_fsconfig:
|
||||
{
|
||||
/*
|
||||
* fsconfig(int, int, char *, void *, int)
|
||||
* NOTE: p4 is nullable and its type might not be a string.
|
||||
*/
|
||||
void *p3, *p4;
|
||||
int cmd = (int) arg2;
|
||||
switch (cmd) {
|
||||
case FSCONFIG_SET_BINARY:
|
||||
case FSCONFIG_SET_STRING:
|
||||
case FSCONFIG_SET_PATH:
|
||||
case FSCONFIG_SET_PATH_EMPTY:
|
||||
p3 = lock_user_string(arg3);
|
||||
if (!p3) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
if (cmd != FSCONFIG_SET_BINARY) {
|
||||
/* key and value must be strings. */
|
||||
p4 = lock_user_string(arg4);
|
||||
} else {
|
||||
/*
|
||||
* Otherwise the value must be a raw buffer with its
|
||||
* length specified in arg5 (aux).
|
||||
*/
|
||||
p4 = lock_user(VERIFY_READ, arg4, arg5, 1);
|
||||
}
|
||||
if (!p4) {
|
||||
unlock_user(p3, arg3, 0);
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
ret = get_errno(sys_fsconfig(arg1, arg2, p3, p4, arg5));
|
||||
unlock_user(p3, arg3, 0);
|
||||
unlock_user(p4, arg4, 0);
|
||||
break;
|
||||
|
||||
case FSCONFIG_SET_FLAG:
|
||||
case FSCONFIG_SET_FD:
|
||||
/* arg4 (value) must be NULL. */
|
||||
if (arg4) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
p3 = lock_user_string(arg3);
|
||||
if (!p3) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
ret = get_errno(sys_fsconfig(arg1, arg2, p3, NULL, arg5));
|
||||
unlock_user(p3, arg3, 0);
|
||||
break;
|
||||
case FSCONFIG_CMD_CREATE:
|
||||
case FSCONFIG_CMD_RECONFIGURE:
|
||||
#ifdef FSCONFIG_CMD_CREATE_EXCL
|
||||
/*
|
||||
* FSCONFIG_CMD_CREATE_EXCL is only available since Linux
|
||||
* 6.6. Guarding it to allow building with pre-6.6 headers.
|
||||
*/
|
||||
case FSCONFIG_CMD_CREATE_EXCL:
|
||||
#endif
|
||||
/* key and value must be NULL, aux must be 0. */
|
||||
if (arg3 || arg4 || arg5) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
ret = get_errno(sys_fsconfig(arg1, arg2, NULL, NULL, 0));
|
||||
break;
|
||||
default:
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
case TARGET_NR_fsmount:
|
||||
ret = get_errno(sys_fsmount(arg1, arg2, arg3));
|
||||
return ret;
|
||||
case TARGET_NR_fspick:
|
||||
{
|
||||
p = lock_user_string(arg2);
|
||||
ret = get_errno(sys_fspick(arg1, p, arg3));
|
||||
unlock_user(p, arg2, 0);
|
||||
}
|
||||
return ret;
|
||||
#endif
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
|
||||
return -TARGET_ENOSYS;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue