https://bugs.kde.org/show_bug.cgi?id=399087
--- Comment #7 from John Reiser <jrei...@bitwagon.com> --- The root cause is a symlink vulnerability! coregrind fails to do the right thing when the target executes int fd_i_am = open("/proc/self/exe", O_RDONLY); upx uses mmap(,,,,fd_i_am,) to replicate portions of the address space of the target. Because coregrind does not virtualize correctly, then upx unfortunately replicates portions of the valgrind tool (memcheck-arm-linux) instead. The simplistic workaround is for coregrind to replace any syscall argument of "/proc/self/exe" with path_to_target. (The complete list of affected syscalls is in the source for 'strace' in its handling of the command-line sequence "-e trace=file".) This workaround fails to recognize "/proc/PID/exe" where PID is the decimal representation of the numeric process ID. The workaround also can fail if the target executes chdir() or chroot(). More generally (and for "defense in depth"), coregrind should protect against any occurrence of "/proc/self/exe" (or equivalent) during pathname resolution by the operating system. At initialization then coregrind should [error checking omitted!] int fd_tool = open("/proc/self/exe", O_RDONLY); /* yes, the tool itself */ struct stat stat_tool; fstat(fd_tool, &stat_tool); int fd_target = open(path_to_target, O_RDONLY); struct stat stat_target; fstat(fd_target, &stat_target); For any successful fd = open() by the target, then coregrind should struct stat stat_fd; fstat(fd, &stat_fd); and compare stat_fd{.st_dev, .st_ino} against stat_tool{.st_dev, .st_ino} to detect the need for virtualization. If so, then close(fd) and set fd = dup(fd_target); System calls other than open() probably are less important, but in theory deserve similar care. For instance, chmod would use open+fstat+check{.st_dev, .st_ino}+fchmod+close. Another approach is to rely on resolution of path_to_target into an absolute path. On linux: int fd = open(path_to_target, O_RDONLY); char abs_path[PATH_MAX]; char tmp[32]; snprintf(tmp, sizeof(tmp), "/proc/self/fd/%d", fd); int n = readlink(tmp, abs_path, -1+ sizeof(abs_path)); abs_path[n] = '\0'; /* ERROR CHECKING OMITTTED */ I consider the {.st_dev, .st_ino} technique to be better. -- You are receiving this mail because: You are watching all bug changes.