提交 ef4467e9 编写于 作者: P Paul Burton 提交者: Riku Voipio

linux-user: respect timezone for settimeofday

The settimeofday syscall accepts a tz argument indicating the desired
timezone to the kernel. QEMU previously ignored any argument provided
by the target program & always passed NULL to the kernel. Instead,
translate the argument & pass along the data userland provided.

Although this argument is described by the settimeofday man page as
obsolete, it is used by systemd as of version 213.
Signed-off-by: NPaul Burton <paul@archlinuxmips.org>
Signed-off-by: NRiku Voipio <riku.voipio@linaro.org>
上级 fd767832
......@@ -935,6 +935,23 @@ static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr,
return 0;
}
static inline abi_long copy_from_user_timezone(struct timezone *tz,
abi_ulong target_tz_addr)
{
struct target_timezone *target_tz;
if (!lock_user_struct(VERIFY_READ, target_tz, target_tz_addr, 1)) {
return -TARGET_EFAULT;
}
__get_user(tz->tz_minuteswest, &target_tz->tz_minuteswest);
__get_user(tz->tz_dsttime, &target_tz->tz_dsttime);
unlock_user_struct(target_tz, target_tz_addr, 0);
return 0;
}
#if defined(TARGET_NR_mq_open) && defined(__NR_mq_open)
#include <mqueue.h>
......@@ -6385,9 +6402,19 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_settimeofday:
{
struct timeval tv;
struct timezone tz, *ptz = NULL;
if (copy_from_user_timeval(&tv, arg1))
goto efault;
ret = get_errno(settimeofday(&tv, NULL));
if (arg2) {
if (copy_from_user_timezone(&tz, arg2)) {
goto efault;
}
ptz = &tz;
}
ret = get_errno(settimeofday(&tv, ptz));
}
break;
#if defined(TARGET_NR_select)
......
......@@ -165,6 +165,11 @@ struct target_timespec {
abi_long tv_nsec;
};
struct target_timezone {
abi_int tz_minuteswest;
abi_int tz_dsttime;
};
struct target_itimerval {
struct target_timeval it_interval;
struct target_timeval it_value;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册