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: Paul Burton <paul@archlinuxmips.org> Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
This commit is contained in:
parent
fd76783243
commit
ef4467e911
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user