diff --git a/src/kernel/emulation/linux/misc/proc_info.c b/src/kernel/emulation/linux/misc/proc_info.c index 003d2396c..20c8698a3 100644 --- a/src/kernel/emulation/linux/misc/proc_info.c +++ b/src/kernel/emulation/linux/misc/proc_info.c @@ -16,6 +16,7 @@ #include "../simple.h" #include "../readline.h" #include "../elfcalls_wrapper.h" +#include "../vchroot_expand.h" #include #include #include @@ -457,7 +458,23 @@ static bool parse_smaps_firstline(const char* line, struct proc_regioninfo* ri, static long _proc_pidinfo_pathinfo(int32_t pid, void* buffer, int32_t bufsize) { char path[64]; + struct vchroot_unexpand_args args; + __simple_sprintf(path, "/proc/%d/exe", pid); + memset(buffer, 0, bufsize); - return sys_readlink(path, buffer, bufsize); + int rv = sys_readlink(path, buffer, bufsize - 1); + + if (rv < 0) + return rv; + + ((char*)buffer)[rv] = 0; + + strcpy(args.path, buffer); + rv = vchroot_unexpand(&args); + if (rv != 0) + return rv; + + strncpy(buffer, args.path, bufsize); + return strlen(args.path); } diff --git a/src/kernel/emulation/linux/vchroot_expand.h b/src/kernel/emulation/linux/vchroot_expand.h index 46d88bd90..e1a2ffd77 100644 --- a/src/kernel/emulation/linux/vchroot_expand.h +++ b/src/kernel/emulation/linux/vchroot_expand.h @@ -4,5 +4,11 @@ int vchroot_expand(struct vchroot_expand_args* args); +struct vchroot_unexpand_args +{ + char path[4096]; +}; +int vchroot_unexpand(struct vchroot_unexpand_args* args); + #endif diff --git a/src/kernel/emulation/linux/vchroot_userspace.c b/src/kernel/emulation/linux/vchroot_userspace.c index 378ec803b..902b0b51e 100644 --- a/src/kernel/emulation/linux/vchroot_userspace.c +++ b/src/kernel/emulation/linux/vchroot_userspace.c @@ -1,5 +1,6 @@ #include +#include "vchroot_expand.h" #ifdef TEST # include # include @@ -461,6 +462,23 @@ int vchroot_fdpath(struct vchroot_fdpath_args* args) return 0; } +int vchroot_unexpand(struct vchroot_unexpand_args* args) +{ + if (memcmp(args->path, prefix_path, prefix_path_len) == 0) + { + int bytes = strlen(args->path + prefix_path_len) + 1; + memmove(args->path, args->path + prefix_path_len, bytes); + } + else + { + int bytes = strlen(args->path) + 1; + memmove(args->path + sizeof(EXIT_PATH) - 1, args->path, bytes); + memcpy(args->path, EXIT_PATH, sizeof(EXIT_PATH) - 1); + } + + return 0; +} + #ifdef TEST int main(int argc, const char** argv) {