diff mbox series

[12/32] bsd-user: Implement getgroups(2) and setgroups(2) system calls.

Message ID 20230827155746.84781-13-kariem.taha2.7@gmail.com
State New
Headers show
Series bsd-user: Implement freebsd process related system calls. | expand

Commit Message

Karim Taha Aug. 27, 2023, 3:57 p.m. UTC
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(+)

Comments

Richard Henderson Aug. 29, 2023, 7:53 p.m. UTC | #1
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 mbox series

Patch

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.
          */