Add os-extattr.c with t2h_freebsd_acl, h2t_freebsd_acl, and t2h_freebsd_acl_type helper functions for ACL operations. Add os-extattr.c to the build and include os-extattr.h in the syscall dispatcher.
Signed-off-by: Stacey Son <[email protected]> Signed-off-by: Warner Losh <[email protected]> Assisted-by: Claude Opus 4.6 (1M context) --- bsd-user/freebsd/os-extattr.c | 116 ++++++++++++++++++++++++++++++++++++++++++ bsd-user/freebsd/os-syscall.c | 2 + 2 files changed, 118 insertions(+) diff --git a/bsd-user/freebsd/os-extattr.c b/bsd-user/freebsd/os-extattr.c new file mode 100644 index 0000000000..0f0c7123dd --- /dev/null +++ b/bsd-user/freebsd/os-extattr.c @@ -0,0 +1,116 @@ +/* + * FreeBSD extend attributes and ACL conversions + * + * Copyright (c) 2013 Stacey D. Son + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include "qemu/osdep.h" + +#ifndef _ACL_PRIVATE +#define _ACL_PRIVATE +#endif +#include <sys/acl.h> + +#include "qemu.h" +#include "qemu-os.h" + +/* + * FreeBSD ACL conversion. + */ +abi_long t2h_freebsd_acl(struct acl *host_acl, abi_ulong target_addr) +{ + uint32_t i; + struct target_freebsd_acl *target_acl; + + if (!lock_user_struct(VERIFY_READ, target_acl, target_addr, 1)) { + return -TARGET_EFAULT; + } + __get_user(host_acl->acl_maxcnt, &target_acl->acl_maxcnt); + __get_user(host_acl->acl_cnt, &target_acl->acl_cnt); + + if (host_acl->acl_maxcnt > ACL_MAX_ENTRIES) { + unlock_user_struct(target_acl, target_addr, 0); + return -TARGET_EINVAL; + } + + for (i = 0; i < host_acl->acl_maxcnt; i++) { + __get_user(host_acl->acl_entry[i].ae_tag, + &target_acl->acl_entry[i].ae_tag); + __get_user(host_acl->acl_entry[i].ae_id, + &target_acl->acl_entry[i].ae_id); + __get_user(host_acl->acl_entry[i].ae_perm, + &target_acl->acl_entry[i].ae_perm); + __get_user(host_acl->acl_entry[i].ae_entry_type, + &target_acl->acl_entry[i].ae_entry_type); + __get_user(host_acl->acl_entry[i].ae_flags, + &target_acl->acl_entry[i].ae_flags); + } + + unlock_user_struct(target_acl, target_addr, 0); + return 0; +} + +abi_long h2t_freebsd_acl(abi_ulong target_addr, struct acl *host_acl) +{ + uint32_t i; + struct target_freebsd_acl *target_acl; + + if (host_acl->acl_maxcnt > ACL_MAX_ENTRIES) { + return -TARGET_EINVAL; + } + + if (!lock_user_struct(VERIFY_WRITE, target_acl, target_addr, 0)) { + return -TARGET_EFAULT; + } + + __put_user(host_acl->acl_maxcnt, &target_acl->acl_maxcnt); + __put_user(host_acl->acl_cnt, &target_acl->acl_cnt); + + for (i = 0; i < host_acl->acl_maxcnt; i++) { + __put_user(host_acl->acl_entry[i].ae_tag, + &target_acl->acl_entry[i].ae_tag); + __put_user(host_acl->acl_entry[i].ae_id, + &target_acl->acl_entry[i].ae_id); + __put_user(host_acl->acl_entry[i].ae_perm, + &target_acl->acl_entry[i].ae_perm); + __put_user(host_acl->acl_entry[i].ae_entry_type, + &target_acl->acl_entry[i].ae_entry_type); + __put_user(host_acl->acl_entry[i].ae_flags, + &target_acl->acl_entry[i].ae_flags); + } + + unlock_user_struct(target_acl, target_addr, 1); + return 0; +} + +abi_long t2h_freebsd_acl_type(acl_type_t *host_type, abi_long target_type) +{ + + switch (target_type) { + case TARGET_FREEBSD_ACL_TYPE_ACCESS_OLD: + *host_type = ACL_TYPE_ACCESS_OLD; + break; + + case TARGET_FREEBSD_ACL_TYPE_DEFAULT_OLD: + *host_type = ACL_TYPE_DEFAULT_OLD; + break; + + case TARGET_FREEBSD_ACL_TYPE_ACCESS: + *host_type = ACL_TYPE_ACCESS; + break; + + case TARGET_FREEBSD_ACL_TYPE_DEFAULT: + *host_type = ACL_TYPE_DEFAULT; + break; + + case TARGET_FREEBSD_ACL_TYPE_NFS4: + *host_type = ACL_TYPE_NFS4; + break; + + default: + return -TARGET_EINVAL; + } + return 0; +} + diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c index 0c729da0ab..f385034a53 100644 --- a/bsd-user/freebsd/os-syscall.c +++ b/bsd-user/freebsd/os-syscall.c @@ -17,6 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. */ +#define _ACL_PRIVATE #include "qemu/osdep.h" #include "qemu/cutils.h" #include "qemu/path.h" @@ -43,6 +44,7 @@ #include "bsd-socket.h" /* BSD dependent syscall shims */ +#include "os-extattr.h" #include "os-stat.h" #include "os-proc.h" #include "os-signal.h" -- 2.52.0
