Message ID | 20230827155746.84781-13-kariem.taha2.7@gmail.com |
---|---|
State | New |
Headers | show |
Series | bsd-user: Implement freebsd process related system calls. | expand |
On 8/27/23 08:57, Karim Taha wrote: > From: Stacey Son <sson@FreeBSD.org> > > Signed-off-by: Stacey Son <sson@FreeBSD.org> > Signed-off-by: Karim Taha <kariem.taha2.7@gmail.com> > --- > bsd-user/bsd-proc.h | 44 +++++++++++++++++++++++++++++++++++ > bsd-user/freebsd/os-syscall.c | 9 +++++++ > 2 files changed, 53 insertions(+) > > diff --git a/bsd-user/bsd-proc.h b/bsd-user/bsd-proc.h > index b6225e520e..ecd6a13c2d 100644 > --- a/bsd-user/bsd-proc.h > +++ b/bsd-user/bsd-proc.h > @@ -41,4 +41,48 @@ static inline abi_long do_bsd_exit(void *cpu_env, abi_long arg1) > return 0; > } > > +/* getgroups(2) */ > +static inline abi_long do_bsd_getgroups(abi_long gidsetsize, abi_long arg2) > +{ > + abi_long ret; > + uint32_t *target_grouplist; > + gid_t *grouplist; > + int i; > + > + grouplist = alloca(gidsetsize * sizeof(gid_t)); Don't use alloca for items that are sized by the guest. Use g_autofree and g_try_new, failing with ENOMEM. > +/* setgroups(2) */ > +static inline abi_long do_bsd_setgroups(abi_long gidsetsize, abi_long arg2) > +{ > + uint32_t *target_grouplist; > + gid_t *grouplist; > + int i; > + > + grouplist = alloca(gidsetsize * sizeof(gid_t)); Likewise. r~
diff --git a/bsd-user/bsd-proc.h b/bsd-user/bsd-proc.h index b6225e520e..ecd6a13c2d 100644 --- a/bsd-user/bsd-proc.h +++ b/bsd-user/bsd-proc.h @@ -41,4 +41,48 @@ static inline abi_long do_bsd_exit(void *cpu_env, abi_long arg1) return 0; } +/* getgroups(2) */ +static inline abi_long do_bsd_getgroups(abi_long gidsetsize, abi_long arg2) +{ + abi_long ret; + uint32_t *target_grouplist; + gid_t *grouplist; + int i; + + grouplist = alloca(gidsetsize * sizeof(gid_t)); + ret = get_errno(getgroups(gidsetsize, grouplist)); + if (gidsetsize != 0) { + if (!is_error(ret)) { + target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0); + if (!target_grouplist) { + return -TARGET_EFAULT; + } + for (i = 0; i < ret; i++) { + target_grouplist[i] = tswap32(grouplist[i]); + } + unlock_user(target_grouplist, arg2, gidsetsize * 2); + } + } + return ret; +} + +/* setgroups(2) */ +static inline abi_long do_bsd_setgroups(abi_long gidsetsize, abi_long arg2) +{ + uint32_t *target_grouplist; + gid_t *grouplist; + int i; + + grouplist = alloca(gidsetsize * sizeof(gid_t)); + target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1); + if (!target_grouplist) { + return -TARGET_EFAULT; + } + for (i = 0; i < gidsetsize; i++) { + grouplist[i] = tswap32(target_grouplist[i]); + } + unlock_user(target_grouplist, arg2, 0); + return get_errno(setgroups(gidsetsize, grouplist)); +} + #endif /* !BSD_PROC_H_ */ diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c index 2224a280ea..17160ab532 100644 --- a/bsd-user/freebsd/os-syscall.c +++ b/bsd-user/freebsd/os-syscall.c @@ -220,6 +220,15 @@ static abi_long freebsd_syscall(void *cpu_env, int num, abi_long arg1, ret = do_bsd_exit(cpu_env, arg1); break; + case TARGET_FREEBSD_NR_getgroups: /* getgroups(2) */ + ret = do_bsd_getgroups(arg1, arg2); + break; + + case TARGET_FREEBSD_NR_setgroups: /* setgroups(2) */ + ret = do_bsd_setgroups(arg1, arg2); + break; + + /* * File system calls. */