diff options
Diffstat (limited to 'app-emulation/qemu/files/qemu-2.1.1-readlink-self.patch')
-rw-r--r-- | app-emulation/qemu/files/qemu-2.1.1-readlink-self.patch | 81 |
1 files changed, 0 insertions, 81 deletions
diff --git a/app-emulation/qemu/files/qemu-2.1.1-readlink-self.patch b/app-emulation/qemu/files/qemu-2.1.1-readlink-self.patch deleted file mode 100644 index 451a9682..00000000 --- a/app-emulation/qemu/files/qemu-2.1.1-readlink-self.patch +++ /dev/null @@ -1,81 +0,0 @@ -fix already in upstream - -From f17f4989fa193fa8279474c5462289a3cfe69aea Mon Sep 17 00:00:00 2001 -From: Mike Frysinger <vapier@chromium.org> -Date: Fri, 8 Aug 2014 09:40:25 +0900 -Subject: [PATCH] linux-user: fix readlink handling with magic exe symlink - -The current code always returns the length of the path when it should -be returning the number of bytes it wrote to the output string. - -Further, readlink is not supposed to append a NUL byte, but the current -snprintf logic will always do just that. - -Even further, if you pass in a length of 0, you're suppoesd to get back -an error (EINVAL), but the current logic just returns 0. - -Further still, if there was an error reading the symlink, we should not -go ahead and try to read the target buffer as it is garbage. - -Simple test for the first two issues: -$ cat test.c -int main() { - char buf[50]; - size_t len; - for (len = 0; len < 10; ++len) { - memset(buf, '!', sizeof(buf)); - ssize_t ret = readlink("/proc/self/exe", buf, len); - buf[20] = '\0'; - printf("readlink(/proc/self/exe, {%s}, %zu) = %zi\n", buf, len, ret); - } - return 0; -} - -Now compare the output of the native: -$ gcc test.c -o /tmp/x -$ /tmp/x -$ strace /tmp/x - -With what qemu does: -$ armv7a-cros-linux-gnueabi-gcc test.c -o /tmp/x -static -$ qemu-arm /tmp/x -$ qemu-arm -strace /tmp/x - -Signed-off-by: Mike Frysinger <vapier@chromium.org> -Signed-off-by: Riku Voipio <riku.voipio@linaro.org> ---- - linux-user/syscall.c | 15 +++++++++++++-- - 1 file changed, 13 insertions(+), 2 deletions(-) - -diff --git a/linux-user/syscall.c b/linux-user/syscall.c -index fccf9f0..7c108ab 100644 ---- a/linux-user/syscall.c -+++ b/linux-user/syscall.c -@@ -6636,11 +6636,22 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, - p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0); - if (!p || !p2) { - ret = -TARGET_EFAULT; -+ } else if (!arg3) { -+ /* Short circuit this for the magic exe check. */ -+ ret = -TARGET_EINVAL; - } else if (is_proc_myself((const char *)p, "exe")) { - char real[PATH_MAX], *temp; - temp = realpath(exec_path, real); -- ret = temp == NULL ? get_errno(-1) : strlen(real) ; -- snprintf((char *)p2, arg3, "%s", real); -+ /* Return value is # of bytes that we wrote to the buffer. */ -+ if (temp == NULL) { -+ ret = get_errno(-1); -+ } else { -+ /* Don't worry about sign mismatch as earlier mapping -+ * logic would have thrown a bad address error. */ -+ ret = MIN(strlen(real), arg3); -+ /* We cannot NUL terminate the string. */ -+ memcpy(p2, real, ret); -+ } - } else { - ret = get_errno(readlink(path(p), p2, arg3)); - } --- -2.0.0 - |