Ping. Any comments on this? Patchwork: http://patchwork.ozlabs.org/patch/1151167/ On Wed, Aug 21, 2019 at 1:19 PM Shu-Chun Weng wrote: > Besides /proc/self|, files under /proc/thread-self and > /proc/self|/task/ also expose host information to the guest > program. This patch adds them to the hijack infrastracture. Note that > is_proc_myself() does not check if the matches the current thread > and is thus only suitable for procfs files that are identical for all > threads in the same process. > > Behavior verified with guest program: > > long main_thread_tid; > > long gettid() { > return syscall(SYS_gettid); > } > > void print_info(const char* cxt, const char* dir) { > char buf[1024]; > FILE* fp; > > snprintf(buf, sizeof(buf), "%s/cmdline", dir); > fp = fopen(buf, "r"); > > if (fp == NULL) { > printf("%s: can't open %s\n", cxt, buf); > } else { > fgets(buf, sizeof(buf), fp); > printf("%s %s cmd: %s\n", cxt, dir, buf); > fclose(fp); > } > > snprintf(buf, sizeof(buf), "%s/maps", dir); > fp = fopen(buf, "r"); > > if (fp == NULL) { > printf("%s: can't open %s\n", cxt, buf); > } else { > char seen[128][128]; > int n = 0, is_new = 0; > while(fgets(buf, sizeof(buf), fp) != NULL) { > const char* p = strrchr(buf, ' '); > if (p == NULL || *(p + 1) == '\n') { > continue; > } > ++p; > is_new = 1; > for (int i = 0; i < n; ++i) { > if (strncmp(p, seen[i], sizeof(seen[i])) == 0) { > is_new = 0; > break; > } > } > if (is_new) { > printf("%s %s map: %s", cxt, dir, p); > if (n < 128) { > strncpy(seen[n], p, sizeof(seen[n])); > seen[n][sizeof(seen[n]) - 1] = '\0'; > ++n; > } > } > } > fclose(fp); > } > } > > void* thread_main(void* _) { > char buf[1024]; > > print_info("Child", "/proc/thread-self"); > > snprintf(buf, sizeof(buf), "/proc/%ld/task/%ld", (long) getpid(), > main_thread_tid); > print_info("Child", buf); > > snprintf(buf, sizeof(buf), "/proc/%ld/task/%ld", (long) getpid(), (long) > gettid()); > print_info("Child", buf); > > return NULL; > } > > int main() { > char buf[1024]; > pthread_t thread; > int ret; > > print_info("Main", "/proc/thread-self"); > print_info("Main", "/proc/self"); > > snprintf(buf, sizeof(buf), "/proc/%ld", (long) getpid()); > print_info("Main", buf); > > main_thread_tid = gettid(); > snprintf(buf, sizeof(buf), "/proc/self/task/%ld", main_thread_tid); > print_info("Main", buf); > > snprintf(buf, sizeof(buf), "/proc/%ld/task/%ld", (long) getpid(), > main_thread_tid); > print_info("Main", buf); > > if ((ret = pthread_create(&thread, NULL, &thread_main, NULL)) < 0) { > printf("ptherad_create failed: %s (%d)\n", strerror(ret), ret); > } > > pthread_join(thread, NULL); > return 0; > } > > Signed-off-by: Shu-Chun Weng > --- > linux-user/syscall.c | 40 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 40 insertions(+) > > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index 8367cb138d..73fe82bcc7 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -6968,17 +6968,57 @@ static int open_self_auxv(void *cpu_env, int fd) > return 0; > } > > +static int consume_task_directories(const char **filename) > +{ > + if (!strncmp(*filename, "task/", strlen("task/"))) { > + *filename += strlen("task/"); > + if (**filename < '1' || **filename > '9') { > + return 0; > + } > + /* > + * Don't care about the exact tid. > + * XXX: this allows opening files under /proc/self|/task/ > where > + * is not a valid thread id. Consider checking if the > file > + * actually exists. > + */ > + const char *p = *filename + 1; > + while (*p >= '0' && *p <= '9') { > + ++p; > + } > + if (*p == '/') { > + *filename = p + 1; > + return 1; > + } else { > + return 0; > + } > + } > + return 1; > +} > + > +/* > + * Determines if filename refer to a procfs file for the current process > or any > + * thread within the current process. This function should only be used > to check > + * for files that have identical contents in all threads, e.g. exec, > maps, etc. > + */ > 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/"); > + if (!consume_task_directories(&filename)) { > + return 0; > + } > + } else if (!strncmp(filename, "thread-self/", > strlen("thread-self/"))) { > + filename += strlen("thread-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); > + if (!consume_task_directories(&filename)) { > + return 0; > + } > } else { > return 0; > } > -- > 2.23.0.rc1.153.gdeed80330f-goog > >