I've sent 3 separate patches using "git send email", please review.

пн, 17 авг. 2020 г. в 18:12, Laurent Vivier <laur...@vivier.eu>:

> Hi,
>
> it seems your patch does several things.
>
> Could you split it into several patches?
> Could you add a description of what the patches do?
> Could you use a tool like "git send-email" or "git publish" to send your
> series?
>
> For the patch moving code from syscall.c to syscall_proc.c, write a
> patch that moves the code without modifying it. And then you can follow
> with a patch fixing what you want.
>
> Thanks,
> Laurent
>
> Le 16/08/2020 à 21:58, Андрей Аладьев a écrit :
> > From: Andrew Aladjev <aladjev.and...@gmail.com
> > <mailto:aladjev.and...@gmail.com>>
> > Date: Sun, 16 Aug 2020 22:50:13 +0300
> > Subject: [PATCH] fixed proc myself (linux user) for musl
> > Buglink: https://bugs.gentoo.org/587230
> > Signed-off-by: Andrew Aladjev <aladjev.and...@gmail.com
> > <mailto:aladjev.and...@gmail.com>>
> > ---
> >  linux-user/Makefile.objs  |  5 +-
> >  linux-user/elfload.c      |  7 ++-
> >  linux-user/exit.c         |  7 ++-
> >  linux-user/main.c         |  2 +-
> >  linux-user/qemu.h         |  1 +
> >  linux-user/syscall.c      | 85 +++++++++++++---------------------
> >  linux-user/syscall_proc.c | 96 +++++++++++++++++++++++++++++++++++++++
> >  linux-user/syscall_proc.h |  8 ++++
> >  8 files changed, 150 insertions(+), 61 deletions(-)
> >  create mode 100644 linux-user/syscall_proc.c
> >  create mode 100644 linux-user/syscall_proc.h
> >
> > diff --git a/linux-user/Makefile.objs b/linux-user/Makefile.objs
> > index 1940910a73..ad84380738 100644
> > --- a/linux-user/Makefile.objs
> > +++ b/linux-user/Makefile.objs
> > @@ -1,7 +1,8 @@
> >  obj-y = main.o syscall.o strace.o mmap.o signal.o \
> >   elfload.o linuxload.o uaccess.o uname.o \
> > - safe-syscall.o $(TARGET_ABI_DIR)/signal.o \
> > -        $(TARGET_ABI_DIR)/cpu_loop.o exit.o fd-trans.o
> > + safe-syscall.o syscall_proc.o \
> > + $(TARGET_ABI_DIR)/cpu_loop.o $(TARGET_ABI_DIR)/signal.o \
> > + exit.o fd-trans.o
> >
> >  obj-$(TARGET_HAS_BFLT) += flatload.o
> >  obj-$(TARGET_I386) += vm86.o
> > diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> > index 619c054cc4..201db61d91 100644
> > --- a/linux-user/elfload.c
> > +++ b/linux-user/elfload.c
> > @@ -2319,7 +2319,10 @@ exit_errmsg:
> >     buffer is sufficiently aligned to present no problems to the host
> >     in accessing data at aligned offsets within the buffer.
> >
> > -   On return: INFO values will be filled in, as necessary or available.
>  */
> > +   On return: INFO values will be filled in, as necessary or available.
> > +
> > +   WARNING: this function won't close "image_fd".
> > +*/
> >
> >  static void load_elf_image(const char *image_name, int image_fd,
> >                             struct image_info *info, char **pinterp_name,
> > @@ -2576,7 +2579,6 @@ static void load_elf_image(const char *image_name,
> > int image_fd,
> >
> >      mmap_unlock();
> >
> > -    close(image_fd);
> >      return;
> >
> >   exit_read:
> > @@ -2610,6 +2612,7 @@ static void load_elf_interp(const char *filename,
> > struct image_info *info,
> >      }
> >
> >      load_elf_image(filename, fd, info, NULL, bprm_buf);
> > +    close(fd);
> >      return;
> >
> >   exit_perror:
> > diff --git a/linux-user/exit.c b/linux-user/exit.c
> > index 1594015444..f0626fc432 100644
> > --- a/linux-user/exit.c
> > +++ b/linux-user/exit.c
> > @@ -28,12 +28,15 @@ extern void __gcov_dump(void);
> >
> >  void preexit_cleanup(CPUArchState *env, int code)
> >  {
> > +    close(execfd);
> > +
> >  #ifdef CONFIG_GPROF
> >          _mcleanup();
> >  #endif
> >  #ifdef CONFIG_GCOV
> >          __gcov_dump();
> >  #endif
> > -        gdb_exit(env, code);
> > -        qemu_plugin_atexit_cb();
> > +
> > +    gdb_exit(env, code);
> > +    qemu_plugin_atexit_cb();
> >  }
> > diff --git a/linux-user/main.c b/linux-user/main.c
> > index 22578b1633..9cc6c1e6da 100644
> > --- a/linux-user/main.c
> > +++ b/linux-user/main.c
> > @@ -48,6 +48,7 @@
> >  #include "crypto/init.h"
> >
> >  char *exec_path;
> > +int execfd;
> >
> >  int singlestep;
> >  static const char *argv0;
> > @@ -628,7 +629,6 @@ int main(int argc, char **argv, char **envp)
> >      int target_argc;
> >      int i;
> >      int ret;
> > -    int execfd;
> >      int log_mask;
> >      unsigned long max_reserved_va;
> >
> > diff --git a/linux-user/qemu.h b/linux-user/qemu.h
> > index 792c74290f..d822f2b9df 100644
> > --- a/linux-user/qemu.h
> > +++ b/linux-user/qemu.h
> > @@ -156,6 +156,7 @@ typedef struct TaskState {
> >  } __attribute__((aligned(16))) TaskState;
> >
> >  extern char *exec_path;
> > +extern int execfd;
> >  void init_task_state(TaskState *ts);
> >  void task_settid(TaskState *);
> >  void stop_all_tasks(void);
> > diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> > index 05f03919ff..483a735c1a 100644
> > --- a/linux-user/syscall.c
> > +++ b/linux-user/syscall.c
> > @@ -122,6 +122,7 @@
> >  #include "qapi/error.h"
> >  #include "fd-trans.h"
> >  #include "tcg/tcg.h"
> > +#include "syscall_proc.h"
> >
> >  #ifndef CLONE_IO
> >  #define CLONE_IO                0x80000000      /* Clone io context */
> > @@ -1104,7 +1105,7 @@ static inline rlim_t target_to_host_rlim(abi_ulong
> > target_rlim)
> >  {
> >      abi_ulong target_rlim_swap;
> >      rlim_t result;
> > -
> > +
> >      target_rlim_swap = tswapal(target_rlim);
> >      if (target_rlim_swap == TARGET_RLIM_INFINITY)
> >          return RLIM_INFINITY;
> > @@ -1112,7 +1113,7 @@ static inline rlim_t target_to_host_rlim(abi_ulong
> > target_rlim)
> >      result = target_rlim_swap;
> >      if (target_rlim_swap != (rlim_t)result)
> >          return RLIM_INFINITY;
> > -
> > +
> >      return result;
> >  }
> >  #endif
> > @@ -1122,13 +1123,13 @@ static inline abi_ulong
> > host_to_target_rlim(rlim_t rlim)
> >  {
> >      abi_ulong target_rlim_swap;
> >      abi_ulong result;
> > -
> > +
> >      if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim)
> >          target_rlim_swap = TARGET_RLIM_INFINITY;
> >      else
> >          target_rlim_swap = rlim;
> >      result = tswapal(target_rlim_swap);
> > -
> > +
> >      return result;
> >  }
> >  #endif
> > @@ -1615,9 +1616,9 @@ static inline abi_long target_to_host_cmsg(struct
> > msghdr *msgh,
> >      abi_ulong target_cmsg_addr;
> >      struct target_cmsghdr *target_cmsg, *target_cmsg_start;
> >      socklen_t space = 0;
> > -
> > +
> >      msg_controllen = tswapal(target_msgh->msg_controllen);
> > -    if (msg_controllen < sizeof (struct target_cmsghdr))
> > +    if (msg_controllen < sizeof (struct target_cmsghdr))
> >          goto the_end;
> >      target_cmsg_addr = tswapal(target_msgh->msg_control);
> >      target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr,
> > msg_controllen, 1);
> > @@ -1703,7 +1704,7 @@ static inline abi_long host_to_target_cmsg(struct
> > target_msghdr *target_msgh,
> >      socklen_t space = 0;
> >
> >      msg_controllen = tswapal(target_msgh->msg_controllen);
> > -    if (msg_controllen < sizeof (struct target_cmsghdr))
> > +    if (msg_controllen < sizeof (struct target_cmsghdr))
> >          goto the_end;
> >      target_cmsg_addr = tswapal(target_msgh->msg_control);
> >      target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr,
> > msg_controllen, 0);
> > @@ -5750,7 +5751,7 @@ abi_long do_set_thread_area(CPUX86State *env,
> > abi_ulong ptr)
> >      }
> >      unlock_user_struct(target_ldt_info, ptr, 1);
> >
> > -    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
> > +    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
> >          ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
> >             return -TARGET_EINVAL;
> >      seg_32bit = ldt_info.flags & 1;
> > @@ -5828,7 +5829,7 @@ static abi_long do_get_thread_area(CPUX86State
> > *env, abi_ulong ptr)
> >      lp = (uint32_t *)(gdt_table + idx);
> >      entry_1 = tswap32(lp[0]);
> >      entry_2 = tswap32(lp[1]);
> > -
> > +
> >      read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
> >      contents = (entry_2 >> 10) & 3;
> >      seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
> > @@ -5844,8 +5845,8 @@ static abi_long do_get_thread_area(CPUX86State
> > *env, abi_ulong ptr)
> >          (read_exec_only << 3) | (limit_in_pages << 4) |
> >          (seg_not_present << 5) | (useable << 6) | (lm << 7);
> >      limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
> > -    base_addr = (entry_1 >> 16) |
> > -        (entry_2 & 0xff000000) |
> > +    base_addr = (entry_1 >> 16) |
> > +        (entry_2 & 0xff000000) |
> >          ((entry_2 & 0xff) << 16);
> >      target_ldt_info->base_addr = tswapal(base_addr);
> >      target_ldt_info->limit = tswap32(limit);
> > @@ -7353,38 +7354,6 @@ static int open_self_auxv(void *cpu_env, int fd)
> >      return 0;
> >  }
> >
> > -static int is_proc_myself(const char *filename, const char *entry)
> > -{
> > -    if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
> > -        filename += strlen("/proc/");
> > -        if (!strncmp(filename, "self/", strlen("self/"))) {
> > -            filename += strlen("self/");
> > -        } else if (*filename >= '1' && *filename <= '9') {
> > -            char myself[80];
> > -            snprintf(myself, sizeof(myself), "%d/", getpid());
> > -            if (!strncmp(filename, myself, strlen(myself))) {
> > -                filename += strlen(myself);
> > -            } else {
> > -                return 0;
> > -            }
> > -        } else {
> > -            return 0;
> > -        }
> > -        if (!strcmp(filename, entry)) {
> > -            return 1;
> > -        }
> > -    }
> > -    return 0;
> > -}
> > -
> > -#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) ||
> \
> > -    defined(TARGET_SPARC) || defined(TARGET_M68K)
> > -static int is_proc(const char *filename, const char *entry)
> > -{
> > -    return strcmp(filename, entry) == 0;
> > -}
> > -#endif
> > -
> >  #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
> >  static int open_net_route(void *cpu_env, int fd)
> >  {
> > @@ -7460,20 +7429,19 @@ static int do_openat(void *cpu_env, int dirfd,
> > const char *pathname, int flags,
> >          { "auxv", open_self_auxv, is_proc_myself },
> >          { "cmdline", open_self_cmdline, is_proc_myself },
> >  #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
> > -        { "/proc/net/route", open_net_route, is_proc },
> > +        { "net/route", open_net_route, is_proc },
> >  #endif
> >  #if defined(TARGET_SPARC)
> > -        { "/proc/cpuinfo", open_cpuinfo, is_proc },
> > +        { "cpuinfo", open_cpuinfo, is_proc },
> >  #endif
> >  #if defined(TARGET_M68K)
> > -        { "/proc/hardware", open_hardware, is_proc },
> > +        { "hardware", open_hardware, is_proc },
> >  #endif
> >          { NULL, NULL, NULL }
> >      };
> >
> > -    if (is_proc_myself(pathname, "exe")) {
> > -        int execfd = qemu_getauxval(AT_EXECFD);
> > -        return execfd ? execfd : safe_openat(dirfd, exec_path, flags,
> > mode);
> > +    if (is_proc_myself_exe(pathname)) {
> > +        return execfd;
> >      }
> >
> >      for (fake_open = fakes; fake_open->filename; fake_open++) {
> > @@ -7728,8 +7696,17 @@ static abi_long do_syscall1(void *cpu_env, int
> > num, abi_long arg1,
> >          return ret;
> >  #endif
> >      case TARGET_NR_close:
> > -        fd_trans_unregister(arg1);
> > -        return get_errno(close(arg1));
> > +        {
> > +            int fd = arg1;
> > +            if (fd == execfd) {
> > +                // We don't need to close execfd.
> > +                // It will be closed on qemu exit.
> > +                return 0;
> > +            }
> > +
> > +            fd_trans_unregister(fd);
> > +            return get_errno(close(fd));
> > +        }
> >
> >      case TARGET_NR_brk:
> >          return do_brk(arg1);
> > @@ -9031,7 +9008,7 @@ static abi_long do_syscall1(void *cpu_env, int
> > num, abi_long arg1,
> >              } else if (!arg3) {
> >                  /* Short circuit this for the magic exe check. */
> >                  ret = -TARGET_EINVAL;
> > -            } else if (is_proc_myself((const char *)p, "exe")) {
> > +            } else if (is_proc_myself_exe((const char *)p)) {
> >                  char real[PATH_MAX], *temp;
> >                  temp = realpath(exec_path, real);
> >                  /* Return value is # of bytes that we wrote to the
> > buffer. */
> > @@ -9060,7 +9037,7 @@ static abi_long do_syscall1(void *cpu_env, int
> > num, abi_long arg1,
> >              p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
> >              if (!p || !p2) {
> >                  ret = -TARGET_EFAULT;
> > -            } else if (is_proc_myself((const char *)p, "exe")) {
> > +            } else if (is_proc_myself_exe((const char *)p)) {
> >                  char real[PATH_MAX], *temp;
> >                  temp = realpath(exec_path, real);
> >                  ret = temp == NULL ? get_errno(-1) : strlen(real) ;
> > @@ -10847,7 +10824,7 @@ static abi_long do_syscall1(void *cpu_env, int
> > num, abi_long arg1,
> >          return get_errno(fchown(arg1, low2highuid(arg2),
> > low2highgid(arg3)));
> >  #if defined(TARGET_NR_fchownat)
> >      case TARGET_NR_fchownat:
> > -        if (!(p = lock_user_string(arg2)))
> > +        if (!(p = lock_user_string(arg2)))
> >              return -TARGET_EFAULT;
> >          ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
> >                                   low2highgid(arg4), arg5));
> > diff --git a/linux-user/syscall_proc.c b/linux-user/syscall_proc.c
> > new file mode 100644
> > index 0000000000..e85ca99c16
> > --- /dev/null
> > +++ b/linux-user/syscall_proc.c
> > @@ -0,0 +1,96 @@
> > +#include "qemu/osdep.h"
> > +#include "elf.h"
> > +
> > +#include "syscall_proc.h"
> > +#include "qemu.h"
> > +
> > +#define PROC "/proc/"
> > +#define SELF "self/"
> > +
> > +#define STARTS_WITH(path, CONSTANT) \
> > +  strlen(path) >= strlen(CONSTANT) && strncmp(path, CONSTANT,
> > strlen(CONSTANT)) == 0
> > +
> > +static inline char *scope_to_proc(const char *path)
> > +{
> > +    if (STARTS_WITH(path, PROC)) {
> > +        return (char *)path + strlen(PROC);
> > +    }
> > +
> > +    return NULL;
> > +}
> > +
> > +static inline char *scope_to_proc_myself(const char *path)
> > +{
> > +    char *scope_path = scope_to_proc(path);
> > +    if (scope_path == NULL) {
> > +        return NULL;
> > +    }
> > +
> > +    if (STARTS_WITH(scope_path, SELF)) {
> > +        return scope_path + strlen(SELF);
> > +    }
> > +
> > +    if (strlen(scope_path) >= 1 && *scope_path >= '1' && *scope_path <=
> > '9') {
> > +        char pid_path[80];
> > +        snprintf(pid_path, sizeof(pid_path), "%d/", getpid());
> > +        if (STARTS_WITH(scope_path, pid_path)) {
> > +            return scope_path + strlen(pid_path);
> > +        }
> > +    }
> > +
> > +    return NULL;
> > +}
> > +
> > +int is_proc(const char *path, const char *entry)
> > +{
> > +    char *scope_path = scope_to_proc(path);
> > +    if (scope_path == NULL) {
> > +        return 0;
> > +    }
> > +
> > +    return strcmp(scope_path, entry) == 0;
> > +}
> > +
> > +int is_proc_myself(const char *path, const char *entry)
> > +{
> > +    char *scope_path = scope_to_proc_myself(path);
> > +    if (scope_path == NULL) {
> > +        return 0;
> > +    }
> > +
> > +    return strcmp(scope_path, entry) == 0;
> > +}
> > +
> > +int is_proc_myself_exe(const char *path)
> > +{
> > +    char *scope_path = scope_to_proc_myself(path);
> > +    if (scope_path == NULL) {
> > +        return 0;
> > +    }
> > +
> > +    // Kernel creates "fd/#{number}" link after opening "exe" link.
> > +    // Both "exe" and "fd/#{number}" can be used by application.
> > +
> > +    // Kernel can provide infinite amount of fd numbers.
> > +    // Qemu is going to always return single global execfd.
> > +
> > +    // So we need to check "exe" and "fd/#{execfd}" only.
> > +
> > +    if (strcmp(scope_path, "exe") == 0) {
> > +        return 1;
> > +    }
> > +
> > +    if (STARTS_WITH(scope_path, "fd/")) {
> > +        scope_path += strlen("fd/");
> > +
> > +        if (strlen(scope_path) >= 1 && *scope_path >= '1' &&
> > *scope_path <= '9') {
> > +            char execfd_path[80];
> > +            snprintf(execfd_path, sizeof(execfd_path), "%d", execfd);
> > +            if (strcmp(scope_path, execfd_path) == 0) {
> > +                return 1;
> > +            }
> > +        }
> > +    }
> > +
> > +    return 0;
> > +}
> > diff --git a/linux-user/syscall_proc.h b/linux-user/syscall_proc.h
> > new file mode 100644
> > index 0000000000..f0e59c0e96
> > --- /dev/null
> > +++ b/linux-user/syscall_proc.h
> > @@ -0,0 +1,8 @@
> > +#ifndef SYSCALL_PROC_H
> > +#define SYSCALL_PROC_H
> > +
> > +int is_proc(const char *path, const char *entry);
> > +int is_proc_myself(const char *path, const char *entry);
> > +int is_proc_myself_exe(const char *path);
> > +
> > +#endif
> > --
> > 2.26.2
> >
>
>

Reply via email to