From f9b455cfd241593f4fbe96c51f9b511fab6c8fc3 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" <ldv@altlinux.org> Date: Tue, 18 Aug 2015 13:25:36 +0000 Subject: [PATCH] Fix time syscall decoding for some personalities * time.c (current_time_t_is_int32): Define. (sys_time): Use it, printnum_int, and printnum_int64 instead of printnum_long. * tests/time.c: New file. * tests/time.test: New test. * tests/Makefile.am (check_PROGRAMS): Add time. (TESTS): Add time.test. * tests/.gitignore: Add time. --- tests/.gitignore | 1 + tests/Makefile.am | 2 ++ tests/time.c | 43 +++++++++++++++++++++++++++++++++++++++++++ tests/time.test | 13 +++++++++++++ time.c | 7 ++++++- 5 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 tests/time.c create mode 100755 tests/time.test diff --git a/tests/.gitignore b/tests/.gitignore index d58e7355..f709d7f2 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -39,6 +39,7 @@ stack-fcall stat stat32 statfs +time uid uid16 uid32 diff --git a/tests/Makefile.am b/tests/Makefile.am index 6b299d11..6fa46d3a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -50,6 +50,7 @@ check_PROGRAMS = \ stat \ stat32 \ statfs \ + time \ uid \ uid16 \ uid32 \ @@ -115,6 +116,7 @@ TESTS = \ pc.test \ ppoll.test \ sun_path.test \ + time.test \ umovestr.test \ umovestr2.test \ unix-yy.test \ diff --git a/tests/time.c b/tests/time.c new file mode 100644 index 00000000..2726b2d0 --- /dev/null +++ b/tests/time.c @@ -0,0 +1,43 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <time.h> +#include <stdio.h> +#include <stdint.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/syscall.h> + +#ifdef __NR_time + +int +main(void) +{ + const size_t page_len = sysconf(_SC_PAGESIZE); + + void *p = mmap(NULL, page_len * 2, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (p == MAP_FAILED || mprotect(p + page_len, page_len, PROT_NONE)) + return 77; + + time_t *p_t = p + page_len - sizeof(time_t); + time_t t = syscall(__NR_time, p_t); + + if ((time_t) -1 == t || t != *p_t) + return 77; + + printf("time\\(\\[%jd\\]\\) += %jd\n", (intmax_t) t, (intmax_t) t); + + return 0; +} + +#else + +int +main(void) +{ + return 77; +} + +#endif diff --git a/tests/time.test b/tests/time.test new file mode 100755 index 00000000..90b1bfb6 --- /dev/null +++ b/tests/time.test @@ -0,0 +1,13 @@ +#!/bin/sh + +# Check time syscall decoding. + +. "${srcdir=.}/init.sh" + +run_prog > /dev/null +OUT="$LOG.out" +run_strace -etime $args > "$OUT" +match_grep "$LOG" "$OUT" +rm -f "$OUT" + +exit 0 diff --git a/time.c b/time.c index dfddc456..920abdf3 100644 --- a/time.c +++ b/time.c @@ -46,8 +46,10 @@ # else # define current_time_t_is_compat (current_wordsize == 4) # endif +# define current_time_t_is_int32 current_time_t_is_compat #else # define current_time_t_is_compat 0 +# define current_time_t_is_int32 (sizeof(time_t) == 4) #endif struct timeval32 @@ -160,7 +162,10 @@ sprint_timespec(char *buf, struct tcb *tcp, long addr) SYS_FUNC(time) { if (exiting(tcp)) { - printnum_long(tcp, tcp->u_arg[0], "%ld"); + if (current_time_t_is_int32) + printnum_int(tcp, tcp->u_arg[0], "%d"); + else + printnum_int64(tcp, tcp->u_arg[0], "%" PRId64); } return 0; } -- 2.40.0