[PATCH] linux-user: Make TARGET_NR_setgroups affect only the current thread

Ilya Leoshkevich posted 1 patch 10 months ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20240131001851.15932-1-iii@linux.ibm.com
Maintainers: Laurent Vivier <laurent@vivier.eu>
There is a newer version of this series
linux-user/syscall.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
[PATCH] linux-user: Make TARGET_NR_setgroups affect only the current thread
Posted by Ilya Leoshkevich 10 months ago
Like TARGET_NR_setuid, TARGET_NR_setgroups should affect only the
calling thread, and not the entire process. Therefore, implement it
using a syscall, and not a libc call.

Cc: qemu-stable@nongnu.org
Fixes: 19b84f3c35d7 ("added setgroups and getgroups syscalls")
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 linux-user/syscall.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ff245dade51..da15d727e16 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7203,11 +7203,17 @@ static inline int tswapid(int id)
 #else
 #define __NR_sys_setresgid __NR_setresgid
 #endif
+#ifdef __NR_setgroups32
+#define __NR_sys_setgroups __NR_setgroups32
+#else
+#define __NR_sys_setgroups __NR_setgroups
+#endif
 
 _syscall1(int, sys_setuid, uid_t, uid)
 _syscall1(int, sys_setgid, gid_t, gid)
 _syscall3(int, sys_setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
 _syscall3(int, sys_setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
+_syscall2(int, sys_setgroups, int, size, gid_t *, grouplist)
 
 void syscall_init(void)
 {
@@ -11772,7 +11778,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
                 unlock_user(target_grouplist, arg2,
                             gidsetsize * sizeof(target_id));
             }
-            return get_errno(setgroups(gidsetsize, grouplist));
+            return get_errno(sys_setgroups(gidsetsize, grouplist));
         }
     case TARGET_NR_fchown:
         return get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
@@ -12108,7 +12114,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
                 }
                 unlock_user(target_grouplist, arg2, 0);
             }
-            return get_errno(setgroups(gidsetsize, grouplist));
+            return get_errno(sys_setgroups(gidsetsize, grouplist));
         }
 #endif
 #ifdef TARGET_NR_fchown32
-- 
2.43.0
Re: [PATCH] linux-user: Make TARGET_NR_setgroups affect only the current thread
Posted by Philippe Mathieu-Daudé 9 months, 4 weeks ago
On 31/1/24 01:18, Ilya Leoshkevich wrote:
> Like TARGET_NR_setuid, TARGET_NR_setgroups should affect only the
> calling thread, and not the entire process. Therefore, implement it
> using a syscall, and not a libc call.
> 
> Cc: qemu-stable@nongnu.org
> Fixes: 19b84f3c35d7 ("added setgroups and getgroups syscalls")
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
>   linux-user/syscall.c | 10 ++++++++--
>   1 file changed, 8 insertions(+), 2 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>


Re: [PATCH] linux-user: Make TARGET_NR_setgroups affect only the current thread
Posted by Ilya Leoshkevich 9 months ago
On Wed, Jan 31, 2024 at 02:10:55PM +0100, Philippe Mathieu-Daudé wrote:
> On 31/1/24 01:18, Ilya Leoshkevich wrote:
> > Like TARGET_NR_setuid, TARGET_NR_setgroups should affect only the
> > calling thread, and not the entire process. Therefore, implement it
> > using a syscall, and not a libc call.
> > 
> > Cc: qemu-stable@nongnu.org
> > Fixes: 19b84f3c35d7 ("added setgroups and getgroups syscalls")
> > Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> > ---
> >   linux-user/syscall.c | 10 ++++++++--
> >   1 file changed, 8 insertions(+), 2 deletions(-)
> 
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>

Thanks for the review!

A few weeks have passed and I wonder if this patch fell through the
cracks. Do I need to do something to have it applied?
Re: [PATCH] linux-user: Make TARGET_NR_setgroups affect only the current thread
Posted by Helge Deller 10 months ago
On 1/31/24 01:18, Ilya Leoshkevich wrote:
> Like TARGET_NR_setuid, TARGET_NR_setgroups should affect only the
> calling thread, and not the entire process. Therefore, implement it
> using a syscall, and not a libc call.
>
> Cc: qemu-stable@nongnu.org
> Fixes: 19b84f3c35d7 ("added setgroups and getgroups syscalls")
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>

Patch seems ok, but just out of interest, how did you noticed?

Helge


> ---
>   linux-user/syscall.c | 10 ++++++++--
>   1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index ff245dade51..da15d727e16 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -7203,11 +7203,17 @@ static inline int tswapid(int id)
>   #else
>   #define __NR_sys_setresgid __NR_setresgid
>   #endif
> +#ifdef __NR_setgroups32
> +#define __NR_sys_setgroups __NR_setgroups32
> +#else
> +#define __NR_sys_setgroups __NR_setgroups
> +#endif
>
>   _syscall1(int, sys_setuid, uid_t, uid)
>   _syscall1(int, sys_setgid, gid_t, gid)
>   _syscall3(int, sys_setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
>   _syscall3(int, sys_setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
> +_syscall2(int, sys_setgroups, int, size, gid_t *, grouplist)
>
>   void syscall_init(void)
>   {
> @@ -11772,7 +11778,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
>                   unlock_user(target_grouplist, arg2,
>                               gidsetsize * sizeof(target_id));
>               }
> -            return get_errno(setgroups(gidsetsize, grouplist));
> +            return get_errno(sys_setgroups(gidsetsize, grouplist));
>           }
>       case TARGET_NR_fchown:
>           return get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
> @@ -12108,7 +12114,7 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
>                   }
>                   unlock_user(target_grouplist, arg2, 0);
>               }
> -            return get_errno(setgroups(gidsetsize, grouplist));
> +            return get_errno(sys_setgroups(gidsetsize, grouplist));
>           }
>   #endif
>   #ifdef TARGET_NR_fchown32
Re: Re: [PATCH] linux-user: Make TARGET_NR_setgroups affect only the current thread
Posted by Ilya Leoshkevich 10 months ago
On Wed, Jan 31, 2024 at 08:53:49AM +0100, Helge Deller wrote:
> On 1/31/24 01:18, Ilya Leoshkevich wrote:
> > Like TARGET_NR_setuid, TARGET_NR_setgroups should affect only the
> > calling thread, and not the entire process. Therefore, implement it
> > using a syscall, and not a libc call.
> > 
> > Cc: qemu-stable@nongnu.org
> > Fixes: 19b84f3c35d7 ("added setgroups and getgroups syscalls")
> > Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> 
> Patch seems ok, but just out of interest, how did you noticed?
> 
> Helge

Our internal users are trying to emulate a larger app, and they were
running into weird crashes between fork() and exec(). I had to
implement syscall catchpoints (posted) and follow-fork-mode child
(still needs a few cleanups before I can post it) to be able to debug
it, and found it was dying here [1], and from there it was easy.

[1] https://sourceware.org/git/?p=glibc.git;a=blob;f=nptl/nptl_setxid.c;h=4bfcfe41882d9b15b8090325bfdc9ceb5ab2693e;hb=36f2487f13e3540be9ee0fb51876b1da72176d3f#l25