Skip to content

Commit

Permalink
linux-user: respect timezone for settimeofday
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
paulburton authored and Riku Voipio committed Jun 29, 2014
1 parent fd76783 commit ef4467e
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
29 changes: 28 additions & 1 deletion linux-user/syscall.c
Expand Up @@ -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>

Expand Down Expand Up @@ -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)
Expand Down
5 changes: 5 additions & 0 deletions linux-user/syscall_defs.h
Expand Up @@ -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;
Expand Down

0 comments on commit ef4467e

Please sign in to comment.