All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] linux-user: handle /proc/self/exe with execve() syscall
@ 2022-09-27 12:43 Laurent Vivier
  2022-09-27 12:43 ` [PATCH v2 1/2] " Laurent Vivier
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Laurent Vivier @ 2022-09-27 12:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: Laurent Vivier

Use exec_path to re-execute the binary from /proc/self/exe

Fix do_openat() that should not use execfd.

v2:
- don't use execfd as it can't be closed and is usable by the child

Laurent Vivier (2):
  linux-user: handle /proc/self/exe with execve() syscall
  linux-user: don't use AT_EXECFD in do_openat()

 linux-user/syscall.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

-- 
2.37.3



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/2] linux-user: handle /proc/self/exe with execve() syscall
  2022-09-27 12:43 [PATCH v2 0/2] linux-user: handle /proc/self/exe with execve() syscall Laurent Vivier
@ 2022-09-27 12:43 ` Laurent Vivier
  2022-10-21 15:10   ` Laurent Vivier
  2022-09-27 12:43 ` [PATCH v2 2/2] linux-user: don't use AT_EXECFD in do_openat() Laurent Vivier
  2022-10-26 15:25 ` [PATCH v2 0/2] linux-user: handle /proc/self/exe with execve() syscall Michael Tokarev
  2 siblings, 1 reply; 9+ messages in thread
From: Laurent Vivier @ 2022-09-27 12:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: Laurent Vivier

If path is /proc/self/exe, use the executable path
provided by exec_path.

Don't use execfd as it is closed by loader_exec() and otherwise
will survive to the exec() syscall and be usable child process.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 linux-user/syscall.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f4091212027c..ddf09d7eb61a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8843,7 +8843,11 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
              * before the execve completes and makes it the other
              * program's problem.
              */
-            ret = get_errno(safe_execve(p, argp, envp));
+            if (is_proc_myself(p, "exe")) {
+                ret = get_errno(safe_execve(exec_path, argp, envp));
+            } else {
+                ret = get_errno(safe_execve(p, argp, envp));
+            }
             unlock_user(p, arg1, 0);
 
             goto execve_end;
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 2/2] linux-user: don't use AT_EXECFD in do_openat()
  2022-09-27 12:43 [PATCH v2 0/2] linux-user: handle /proc/self/exe with execve() syscall Laurent Vivier
  2022-09-27 12:43 ` [PATCH v2 1/2] " Laurent Vivier
@ 2022-09-27 12:43 ` Laurent Vivier
  2022-10-21 15:10   ` Laurent Vivier
  2022-10-26 15:25 ` [PATCH v2 0/2] linux-user: handle /proc/self/exe with execve() syscall Michael Tokarev
  2 siblings, 1 reply; 9+ messages in thread
From: Laurent Vivier @ 2022-09-27 12:43 UTC (permalink / raw)
  To: qemu-devel; +Cc: Laurent Vivier

AT_EXECFD gives access to the binary file even if
it is not readable (only executable).

Moreover it can be opened with flags and mode that are not the ones
provided by do_openat() caller.

And it is not available because loader_exec() has closed it.

To avoid that, use only safe_openat() with the exec_path.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 linux-user/syscall.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ddf09d7eb61a..0c80e9d68e28 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8263,8 +8263,7 @@ static int do_openat(CPUArchState *cpu_env, int dirfd, const char *pathname, int
     };
 
     if (is_proc_myself(pathname, "exe")) {
-        int execfd = qemu_getauxval(AT_EXECFD);
-        return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode);
+        return safe_openat(dirfd, exec_path, flags, mode);
     }
 
     for (fake_open = fakes; fake_open->filename; fake_open++) {
-- 
2.37.3



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 1/2] linux-user: handle /proc/self/exe with execve() syscall
  2022-09-27 12:43 ` [PATCH v2 1/2] " Laurent Vivier
@ 2022-10-21 15:10   ` Laurent Vivier
  0 siblings, 0 replies; 9+ messages in thread
From: Laurent Vivier @ 2022-10-21 15:10 UTC (permalink / raw)
  To: qemu-devel

Le 27/09/2022 à 14:43, Laurent Vivier a écrit :
> If path is /proc/self/exe, use the executable path
> provided by exec_path.
> 
> Don't use execfd as it is closed by loader_exec() and otherwise
> will survive to the exec() syscall and be usable child process.
> 
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
>   linux-user/syscall.c | 6 +++++-
>   1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index f4091212027c..ddf09d7eb61a 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -8843,7 +8843,11 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
>                * before the execve completes and makes it the other
>                * program's problem.
>                */
> -            ret = get_errno(safe_execve(p, argp, envp));
> +            if (is_proc_myself(p, "exe")) {
> +                ret = get_errno(safe_execve(exec_path, argp, envp));
> +            } else {
> +                ret = get_errno(safe_execve(p, argp, envp));
> +            }
>               unlock_user(p, arg1, 0);
>   
>               goto execve_end;

Applied to my linux-user-for-7.2 branch.

Thanks,
Laurent


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/2] linux-user: don't use AT_EXECFD in do_openat()
  2022-09-27 12:43 ` [PATCH v2 2/2] linux-user: don't use AT_EXECFD in do_openat() Laurent Vivier
@ 2022-10-21 15:10   ` Laurent Vivier
  0 siblings, 0 replies; 9+ messages in thread
From: Laurent Vivier @ 2022-10-21 15:10 UTC (permalink / raw)
  To: qemu-devel

Le 27/09/2022 à 14:43, Laurent Vivier a écrit :
> AT_EXECFD gives access to the binary file even if
> it is not readable (only executable).
> 
> Moreover it can be opened with flags and mode that are not the ones
> provided by do_openat() caller.
> 
> And it is not available because loader_exec() has closed it.
> 
> To avoid that, use only safe_openat() with the exec_path.
> 
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
>   linux-user/syscall.c | 3 +--
>   1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index ddf09d7eb61a..0c80e9d68e28 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -8263,8 +8263,7 @@ static int do_openat(CPUArchState *cpu_env, int dirfd, const char *pathname, int
>       };
>   
>       if (is_proc_myself(pathname, "exe")) {
> -        int execfd = qemu_getauxval(AT_EXECFD);
> -        return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode);
> +        return safe_openat(dirfd, exec_path, flags, mode);
>       }
>   
>       for (fake_open = fakes; fake_open->filename; fake_open++) {

Applied to my linux-user-for-7.2 branch.

Thanks,
Laurent



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 0/2] linux-user: handle /proc/self/exe with execve() syscall
  2022-09-27 12:43 [PATCH v2 0/2] linux-user: handle /proc/self/exe with execve() syscall Laurent Vivier
  2022-09-27 12:43 ` [PATCH v2 1/2] " Laurent Vivier
  2022-09-27 12:43 ` [PATCH v2 2/2] linux-user: don't use AT_EXECFD in do_openat() Laurent Vivier
@ 2022-10-26 15:25 ` Michael Tokarev
  2022-10-27  6:40   ` Laurent Vivier
  2 siblings, 1 reply; 9+ messages in thread
From: Michael Tokarev @ 2022-10-26 15:25 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel

27.09.2022 15:43, Laurent Vivier wrote:
> Use exec_path to re-execute the binary from /proc/self/exe
> 
> Fix do_openat() that should not use execfd.
> 
> v2:
> - don't use execfd as it can't be closed and is usable by the child

Why can't it be closed? I mean, how about O_CLOEXEC?

Your initial usage of execveat() seemed very elegant.

Thanks,

/mjt


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 0/2] linux-user: handle /proc/self/exe with execve() syscall
  2022-10-26 15:25 ` [PATCH v2 0/2] linux-user: handle /proc/self/exe with execve() syscall Michael Tokarev
@ 2022-10-27  6:40   ` Laurent Vivier
  2022-10-27 10:42     ` Michael Tokarev
       [not found]     ` <ff22a2ac-d058-2448-0e76-03223f7f46dc@tls.msk.ru>
  0 siblings, 2 replies; 9+ messages in thread
From: Laurent Vivier @ 2022-10-27  6:40 UTC (permalink / raw)
  To: Michael Tokarev, qemu-devel

Le 26/10/2022 à 17:25, Michael Tokarev a écrit :
> 27.09.2022 15:43, Laurent Vivier wrote:
>> Use exec_path to re-execute the binary from /proc/self/exe
>>
>> Fix do_openat() that should not use execfd.
>>
>> v2:
>> - don't use execfd as it can't be closed and is usable by the child
> 
> Why can't it be closed? I mean, how about O_CLOEXEC?

I tried O_CLOEXEC, but it seems the fd is closed before it is needed by execveat() to re-spawn the 
process, so it exits with an error (something like EBADF)

Thanks,
Laurent



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 0/2] linux-user: handle /proc/self/exe with execve() syscall
  2022-10-27  6:40   ` Laurent Vivier
@ 2022-10-27 10:42     ` Michael Tokarev
       [not found]     ` <ff22a2ac-d058-2448-0e76-03223f7f46dc@tls.msk.ru>
  1 sibling, 0 replies; 9+ messages in thread
From: Michael Tokarev @ 2022-10-27 10:42 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel

27.10.2022 09:40, Laurent Vivier wrote:
..
> I tried O_CLOEXEC, but it seems the fd is closed before it is needed by execveat() to re-spawn the process, so it exits with an error (something like 
> EBADF)

It works here for me with a simple test program:

#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/syscall.h>
#define AT_EMPTY_PATH		0x1000

static char *argv[] = { "ls", NULL };
static char *envp[] = { NULL };

int main(void) {
   int fd = open("/usr/bin/ls", O_RDONLY);
   fcntl(fd, F_SETFD, O_CLOEXEC);
   //execveat(fd, "", argv, envp, AT_EMPTY_PATH);
   syscall(__NR_execveat, fd, "", argv, envp, AT_EMPTY_PATH);
   return 0;
}


/mjt


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 0/2] linux-user: handle /proc/self/exe with execve() syscall
       [not found]     ` <ff22a2ac-d058-2448-0e76-03223f7f46dc@tls.msk.ru>
@ 2022-10-27 12:09       ` Michael Tokarev
  0 siblings, 0 replies; 9+ messages in thread
From: Michael Tokarev @ 2022-10-27 12:09 UTC (permalink / raw)
  To: Laurent Vivier, qemu-devel

27.10.2022 13:42, Michael Tokarev wrote:
> 27.10.2022 09:40, Laurent Vivier wrote:
> ..
>> I tried O_CLOEXEC, but it seems the fd is closed before it is needed by execveat() to re-spawn the process, so it exits with an error (something 
>> like EBADF)
> 
> It works here for me with a simple test program:
> 
> #include <sys/types.h>
> #include <fcntl.h>
> #include <unistd.h>
> #include <sys/syscall.h>
> #define AT_EMPTY_PATH        0x1000
> 
> static char *argv[] = { "ls", NULL };
> static char *envp[] = { NULL };
> 
> int main(void) {
>    int fd = open("/usr/bin/ls", O_RDONLY);
>    fcntl(fd, F_SETFD, O_CLOEXEC);
>    //execveat(fd, "", argv, envp, AT_EMPTY_PATH);
>    syscall(__NR_execveat, fd, "", argv, envp, AT_EMPTY_PATH);
>    return 0;
> }

But for some reason it does not close this fd# on exec.

  static char *argv[] = { "ls", "-l", "/proc/self/fd", NULL };

shows this.

Hmm. Ok. Let's keep it the way you did :)

/mjt


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-10-27 12:11 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-27 12:43 [PATCH v2 0/2] linux-user: handle /proc/self/exe with execve() syscall Laurent Vivier
2022-09-27 12:43 ` [PATCH v2 1/2] " Laurent Vivier
2022-10-21 15:10   ` Laurent Vivier
2022-09-27 12:43 ` [PATCH v2 2/2] linux-user: don't use AT_EXECFD in do_openat() Laurent Vivier
2022-10-21 15:10   ` Laurent Vivier
2022-10-26 15:25 ` [PATCH v2 0/2] linux-user: handle /proc/self/exe with execve() syscall Michael Tokarev
2022-10-27  6:40   ` Laurent Vivier
2022-10-27 10:42     ` Michael Tokarev
     [not found]     ` <ff22a2ac-d058-2448-0e76-03223f7f46dc@tls.msk.ru>
2022-10-27 12:09       ` Michael Tokarev

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.