[PATCH v6 12/13] tests/xetitimer: Use syscalls instead of libc functions
Dmitry V. Levin
ldv at altlinux.org
Wed Apr 1 00:06:47 UTC 2020
On Fri, Mar 20, 2020 at 03:09:38PM -0700, Alistair Francis wrote:
> The new glibc implementation for y2038 safe arches (32-bit arch with
> 64-bit time_t) will set the itimerval struct inside libc instead of
> inside the kernel. This is becuase the kernel expects a 32-bit version
> of timeval while libc exposes a 64-bit version. As libc sets this, when
> we pass a faulting pointer we will get a segfault instead of the kernel
> reporint EFAULT back.
>
> To avoid a seg fault let's use the kernel's equivilent of struct
> __kernel_old_itimerval in the tests and call the syscall directly
> instead of using libc. This way we can trigger the kernels EFAULT
> response correctly.
>
> Signed-off-by: Alistair Francis <alistair.francis at wdc.com>
> ---
> tests/xetitimer.c | 36 +++++++++++++++++++++++-------------
> 1 file changed, 23 insertions(+), 13 deletions(-)
>
> diff --git a/tests/xetitimer.c b/tests/xetitimer.c
> index c49bf87c..e622f59f 100644
> --- a/tests/xetitimer.c
> +++ b/tests/xetitimer.c
> @@ -14,11 +14,17 @@
> #include <sys/time.h>
> #include <unistd.h>
> #include "scno.h"
> +#include "kernel_timeval.h"
> +
> +typedef struct {
> + kernel_old_timeval_t it_interval;
> + kernel_old_timeval_t it_value;
> +} kernel_old_itimerval_t;
>
> int
> main(void)
> {
> - static const struct itimerval new = {
> + static const kernel_old_itimerval_t new = {
> .it_interval = { 0xc0de1, 0xc0de2 },
> .it_value = { 0xc0de3, 0xc0de4 }
> };
> @@ -27,12 +33,12 @@ main(void)
> static const kernel_ulong_t bogus_timer =
> (kernel_ulong_t) 0xfacefeeddeadbeefULL;
>
> - TAIL_ALLOC_OBJECT_CONST_PTR(struct itimerval, p_old);
> - struct itimerval *const p_new = tail_memdup(&new, sizeof(new));
> + TAIL_ALLOC_OBJECT_CONST_PTR(kernel_old_itimerval_t, p_old);
> + kernel_old_itimerval_t *const p_new = tail_memdup(&new, sizeof(new));
> void *const efault = tail_alloc(sizeof(new) - 8);
> long rc;
>
> - if (setitimer(ITIMER_REAL, p_new, NULL))
> + if (syscall(__NR_setitimer, ITIMER_REAL, p_new, NULL))
> perror_msg_and_skip("setitimer");
> printf("setitimer(ITIMER_REAL"
> ", {it_interval={tv_sec=%lld, tv_usec=%llu}"
> @@ -44,7 +50,7 @@ main(void)
> zero_extend_signed_to_ull(new.it_value.tv_usec));
>
> fill_memory(p_old, sizeof(*p_old));
> - if (getitimer(ITIMER_REAL, p_old))
> + if (syscall(__NR_getitimer, ITIMER_REAL, p_old))
> perror_msg_and_skip("getitimer");
> printf("getitimer(ITIMER_REAL"
> ", {it_interval={tv_sec=%lld, tv_usec=%llu}"
> @@ -55,7 +61,7 @@ main(void)
> zero_extend_signed_to_ull(p_old->it_value.tv_usec));
>
> fill_memory(p_old, sizeof(*p_old));
> - setitimer(ITIMER_REAL, p_new, p_old);
> + syscall(__NR_setitimer, ITIMER_REAL, p_new, p_old);
> printf("setitimer(ITIMER_REAL"
> ", {it_interval={tv_sec=%lld, tv_usec=%llu}"
> ", it_value={tv_sec=%lld, tv_usec=%llu}}"
> @@ -70,10 +76,10 @@ main(void)
> (long long) p_old->it_value.tv_sec,
> zero_extend_signed_to_ull(p_old->it_value.tv_usec));
>
> - rc = getitimer(ITIMER_REAL, efault);
> + rc = syscall(__NR_getitimer, ITIMER_REAL, efault);
> printf("getitimer(ITIMER_REAL, %p) = %s\n", efault, sprintrc(rc));
>
> - rc = setitimer(ITIMER_REAL, p_new, efault);
> + rc = syscall(__NR_setitimer, ITIMER_REAL, p_new, efault);
> printf("setitimer(ITIMER_REAL"
> ", {it_interval={tv_sec=%lld, tv_usec=%llu}"
> ", it_value={tv_sec=%lld, tv_usec=%llu}}, %p) = %s\n",
> @@ -83,7 +89,7 @@ main(void)
> zero_extend_signed_to_ull(new.it_value.tv_usec),
> efault, sprintrc(rc));
>
> - rc = setitimer(ITIMER_REAL, efault, p_old);
> + rc = syscall(__NR_setitimer, ITIMER_REAL, efault, p_old);
> printf("setitimer(ITIMER_REAL, %p, %p) = %s\n",
> efault, p_old, sprintrc(rc));
>
> @@ -147,10 +153,14 @@ main(void)
>
> p_new->it_interval.tv_sec = 0xdeadbeefU;
> p_new->it_interval.tv_usec = 0xfacefeedU;
> - p_new->it_value.tv_sec = (time_t) 0xcafef00ddeadbeefLL;
> - p_new->it_value.tv_usec = (suseconds_t) 0xbadc0dedfacefeedLL;
> -
> - rc = setitimer(ITIMER_REAL, p_new, p_old);
> + p_new->it_value.tv_sec = (kernel_long_t) 0xcafef00ddeadbeefLL;
> +# if defined __sparc__ && defined __arch64__
> + p_new->it_value.tv_usec = (int) 0xbadc0dedfacefeedLL;
> +# else
> + p_new->it_value.tv_usec = (kernel_long_t) 0xbadc0dedfacefeedLL;
> +# endif
Wouldn't it be better to use typeof instead?
--
ldv
More information about the Strace-devel
mailing list