mbox series

[v2,0/2] linux-user: handle /proc/self/exe with execve() syscall

Message ID 20220927124357.688536-1-laurent@vivier.eu (mailing list archive)
Headers show
Series linux-user: handle /proc/self/exe with execve() syscall | expand

Message

Laurent Vivier Sept. 27, 2022, 12:43 p.m. UTC
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(-)

Comments

Michael Tokarev Oct. 26, 2022, 3:25 p.m. UTC | #1
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
Laurent Vivier Oct. 27, 2022, 6:40 a.m. UTC | #2
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
Michael Tokarev Oct. 27, 2022, 10:42 a.m. UTC | #3
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
Michael Tokarev Oct. 27, 2022, 12:09 p.m. UTC | #4
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