提交 0c1592d9 编写于 作者: P Peter Maydell 提交者: Aurelien Jarno

linux-user: Fix large seeks by 32 bit guest on 64 bit host

When emulating a 32 bit Linux user-mode program on a 64 bit target
we implement the llseek syscall in terms of lseek. Correct a bug
which meant we were silently casting the result of host lseek()
to a 32 bit integer as it passed through get_errno() and thus
throwing away the top half.

We also don't try to store the result back to userspace unless
the seek succeeded; this matches the kernel behaviour.

Thanks to Eoghan Sherry for identifying the problem and suggesting
a solution.
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: NAurelien Jarno <aurelien@aurel32.net>
上级 26883c69
......@@ -6127,16 +6127,20 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#ifdef TARGET_NR__llseek /* Not on alpha */
case TARGET_NR__llseek:
{
int64_t res;
#if !defined(__NR_llseek)
ret = get_errno(lseek(arg1, ((uint64_t )arg2 << 32) | arg3, arg5));
if (put_user_s64(ret, arg4))
goto efault;
res = lseek(arg1, ((uint64_t)arg2 << 32) | arg3, arg5);
if (res == -1) {
ret = get_errno(res);
} else {
ret = 0;
}
#else
int64_t res;
ret = get_errno(_llseek(arg1, arg2, arg3, &res, arg5));
if (put_user_s64(res, arg4))
goto efault;
#endif
if ((ret == 0) && put_user_s64(res, arg4)) {
goto efault;
}
}
break;
#endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册