diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index e4a99e43..0d5b1927 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -3213,37 +3213,54 @@ int main_loop(struct thread_data_s *my_thread) memset(pathbuf, '\0', sizeof(pathbuf)); /* check argument 1 dirfd */ - if ((int)w.sr.args[0] != AT_FDCWD) { + ret = do_strncpy_from_user(fd, pathbuf, + (void *)w.sr.args[1], + PATH_MAX); + __dprintf("openat(dirfd == AT_FDCWD)\n"); + if (ret >= PATH_MAX) { + ret = -ENAMETOOLONG; + } + if (ret < 0) { + do_syscall_return(fd, cpu, ret, 0, 0, 0, 0); + break; + } + + if ((int)w.sr.args[0] != AT_FDCWD && + pathbuf[0] != '/') { /* dirfd != AT_FDCWD */ __dprintf("openat(dirfd != AT_FDCWD)\n"); - snprintf(tmpbuf, sizeof(tmpbuf), "/proc/self/fd/%d", (int)w.sr.args[0]); - ret = readlink(tmpbuf, pathbuf, sizeof(pathbuf) - 1); + snprintf(tmpbuf, sizeof(tmpbuf), + "/proc/self/fd/%d", (int)w.sr.args[0]); + ret = readlink(tmpbuf, pathbuf, + sizeof(pathbuf) - 1); + if (ret == -1 && + (errno == ENOENT || + errno == EINVAL)) { + do_syscall_return(fd, cpu, -EBADF, 0, 0, + 0, 0); + break; + } if (ret < 0) { - do_syscall_return(fd, cpu, -errno, 0, 0, 0, 0); + do_syscall_return(fd, cpu, -errno, 0, 0, + 0, 0); break; } __dprintf(" %s -> %s\n", tmpbuf, pathbuf); - ret = do_strncpy_from_user(fd, tmpbuf, (void *)w.sr.args[1], PATH_MAX); + ret = do_strncpy_from_user(fd, tmpbuf, + (void *)w.sr.args[1], + PATH_MAX); if (ret >= PATH_MAX) { ret = -ENAMETOOLONG; } if (ret < 0) { - do_syscall_return(fd, cpu, ret, 0, 0, 0, 0); + do_syscall_return(fd, cpu, ret, 0, 0, 0, + 0); break; } strncat(pathbuf, "/", 1); strncat(pathbuf, tmpbuf, strlen(tmpbuf) + 1); - } else { - /* dirfd == AT_FDCWD */ - __dprintf("openat(dirfd == AT_FDCWD)\n"); - ret = do_strncpy_from_user(fd, pathbuf, (void *)w.sr.args[1], PATH_MAX); - if (ret >= PATH_MAX) { - ret = -ENAMETOOLONG; - } - if (ret < 0) { - do_syscall_return(fd, cpu, ret, 0, 0, 0, 0); - break; - } + } + else { } __dprintf("openat: %s\n", pathbuf); diff --git a/kernel/syscall.c b/kernel/syscall.c index d3c0f6f4..a1a95fbb 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -9481,3 +9481,4 @@ long syscall(int num, ihk_mc_user_context_t *ctx) return l; } + \ No newline at end of file diff --git a/lib/string.c b/lib/string.c index ab194e27..4548261d 100644 --- a/lib/string.c +++ b/lib/string.c @@ -354,19 +354,4 @@ int flatten_strings_from_user(int nr_strings, char *first, char **strings, char p = strchr(p, '\0') + 1; } - for (string_i = 0; string_i < nr_strings; ++string_i) { - char *userp; - _flat[n++] = p - (char *)_flat; - - ret = getlong_user((long *)&userp, (void *)(strings + string_i)); - if (ret < 0) - return ret; - - strcpy_from_user(p, userp); - p = strchr(p, '\0') + 1; - } - _flat[n] = 0; - - *flat = (char *)_flat; - return full_len; -} + for (string_i = 0; string_i < nr_strings; ++string_ \ No newline at end of file