Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 654506 Details for
Bug 587230
app-emulation/qemu - sys-apps/install-xattr segfaults in qemu-arm-user
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
incomplete patch
linux_user_syscall_proc.patch (text/plain), 10.53 KB, created by
Andrew Aladjev
on 2020-08-13 20:49:33 UTC
(
hide
)
Description:
incomplete patch
Filename:
MIME Type:
Creator:
Andrew Aladjev
Created:
2020-08-13 20:49:33 UTC
Size:
10.53 KB
patch
obsolete
>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/syscall.c b/linux-user/syscall.c >index 05f03919ff..d6b02224a9 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,18 +7429,18 @@ 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")) { >+ if (is_proc_myself_exe(pathname)) { > int execfd = qemu_getauxval(AT_EXECFD); > return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode); > } >@@ -9031,7 +9000,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 +9029,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 +10816,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..869102f3fe >--- /dev/null >+++ b/linux-user/syscall_proc.c >@@ -0,0 +1,95 @@ >+#include "syscall_proc.h" >+#include "qemu/osdep.h" >+#include "elf.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/#{global_execfd}" only. >+ >+ if (strcmp(scope_path, "exe") == 0) { >+ return 1; >+ } >+ >+ if (STARTS_WITH(scope_path, "fd/")) { >+ scope_path += strlen("fd/"); >+ >+ int execfd = qemu_getauxval(AT_EXECFD); >+ if (strlen(scope_path) >= 1 && *scope_path >= '1' && *scope_path <= '9' && execfd) { >+ 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
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 587230
:
653834
|
654506
|
654982
|
659016