/* * Check decoding of setitimer and getitimer syscalls. * * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@altlinux.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "tests.h" #include <stdio.h> #include <stdint.h> #include <sys/time.h> #include <unistd.h> #include <asm/unistd.h> int main(void) { static const struct itimerval new = { .it_interval = { 0xc0de1, 0xc0de2 }, .it_value = { 0xc0de3, 0xc0de4 } }; static const kernel_ulong_t long_timer = F8ILL_KULONG_MASK | ITIMER_REAL; 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)); void *const efault = tail_alloc(sizeof(new) - 8); long rc; if (setitimer(ITIMER_REAL, p_new, NULL)) perror_msg_and_skip("setitimer"); printf("setitimer(ITIMER_REAL" ", {it_interval={tv_sec=%lld, tv_usec=%llu}" ", it_value={tv_sec=%lld, tv_usec=%llu}}" ", NULL) = 0\n", (long long) new.it_interval.tv_sec, zero_extend_signed_to_ull(new.it_interval.tv_usec), (long long) new.it_value.tv_sec, zero_extend_signed_to_ull(new.it_value.tv_usec)); fill_memory(p_old, sizeof(*p_old)); if (getitimer(ITIMER_REAL, p_old)) perror_msg_and_skip("getitimer"); printf("getitimer(ITIMER_REAL" ", {it_interval={tv_sec=%lld, tv_usec=%llu}" ", it_value={tv_sec=%lld, tv_usec=%llu}}) = 0\n", (long long) p_old->it_interval.tv_sec, zero_extend_signed_to_ull(p_old->it_interval.tv_usec), (long long) p_old->it_value.tv_sec, 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); printf("setitimer(ITIMER_REAL" ", {it_interval={tv_sec=%lld, tv_usec=%llu}" ", it_value={tv_sec=%lld, tv_usec=%llu}}" ", {it_interval={tv_sec=%lld, tv_usec=%llu}" ", it_value={tv_sec=%lld, tv_usec=%llu}}) = 0\n", (long long) new.it_interval.tv_sec, zero_extend_signed_to_ull(new.it_interval.tv_usec), (long long) new.it_value.tv_sec, zero_extend_signed_to_ull(new.it_value.tv_usec), (long long) p_old->it_interval.tv_sec, zero_extend_signed_to_ull(p_old->it_interval.tv_usec), (long long) p_old->it_value.tv_sec, zero_extend_signed_to_ull(p_old->it_value.tv_usec)); rc = getitimer(ITIMER_REAL, efault); printf("getitimer(ITIMER_REAL, %p) = %s\n", efault, sprintrc(rc)); rc = 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", (long long) new.it_interval.tv_sec, zero_extend_signed_to_ull(new.it_interval.tv_usec), (long long) new.it_value.tv_sec, zero_extend_signed_to_ull(new.it_value.tv_usec), efault, sprintrc(rc)); rc = setitimer(ITIMER_REAL, efault, p_old); printf("setitimer(ITIMER_REAL, %p, %p) = %s\n", efault, p_old, sprintrc(rc)); fill_memory(p_old, sizeof(*p_old)); rc = syscall(__NR_setitimer, long_timer, p_new, p_old); printf("setitimer(ITIMER_REAL" ", {it_interval={tv_sec=%lld, tv_usec=%llu}" ", it_value={tv_sec=%lld, tv_usec=%llu}}" ", {it_interval={tv_sec=%lld, tv_usec=%llu}" ", it_value={tv_sec=%lld, tv_usec=%llu}}) = %s\n", (long long) new.it_interval.tv_sec, zero_extend_signed_to_ull(new.it_interval.tv_usec), (long long) new.it_value.tv_sec, zero_extend_signed_to_ull(new.it_value.tv_usec), (long long) p_old->it_interval.tv_sec, zero_extend_signed_to_ull(p_old->it_interval.tv_usec), (long long) p_old->it_value.tv_sec, zero_extend_signed_to_ull(p_old->it_value.tv_usec), sprintrc(rc)); fill_memory(p_old, sizeof(*p_old)); rc = syscall(__NR_getitimer, long_timer, p_old); printf("getitimer(ITIMER_REAL" ", {it_interval={tv_sec=%lld, tv_usec=%llu}" ", it_value={tv_sec=%lld, tv_usec=%llu}}) = %s\n", (long long) p_old->it_interval.tv_sec, zero_extend_signed_to_ull(p_old->it_interval.tv_usec), (long long) p_old->it_value.tv_sec, zero_extend_signed_to_ull(p_old->it_value.tv_usec), sprintrc(rc)); rc = syscall(__NR_setitimer, bogus_timer, p_new, p_old); printf("setitimer(%#x /* ITIMER_??? */" ", {it_interval={tv_sec=%lld, tv_usec=%llu}" ", it_value={tv_sec=%lld, tv_usec=%llu}}, %p) = %s\n", (int) bogus_timer, (long long) new.it_interval.tv_sec, zero_extend_signed_to_ull(new.it_interval.tv_usec), (long long) new.it_value.tv_sec, zero_extend_signed_to_ull(new.it_value.tv_usec), p_old, sprintrc(rc)); rc = syscall(__NR_getitimer, bogus_timer, p_old); printf("getitimer(%#x /* ITIMER_??? */, %p) = %s\n", (int) bogus_timer, p_old, sprintrc(rc)); if (F8ILL_KULONG_SUPPORTED) { const kernel_ulong_t ill_new = f8ill_ptr_to_kulong(p_new); const kernel_ulong_t ill_old = f8ill_ptr_to_kulong(p_old); rc = syscall(__NR_setitimer, long_timer, ill_new, ill_old); printf("setitimer(ITIMER_REAL, %#llx, %#llx) = %s\n", (unsigned long long) ill_new, (unsigned long long) ill_old, sprintrc(rc)); rc = syscall(__NR_getitimer, long_timer, ill_old); printf("getitimer(ITIMER_REAL, %#llx) = %s\n", (unsigned long long) ill_old, sprintrc(rc)); } 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); printf("setitimer(ITIMER_REAL" ", {it_interval={tv_sec=%lld, tv_usec=%llu}" ", it_value={tv_sec=%lld, tv_usec=%llu}}, %p) = %s\n", (long long) p_new->it_interval.tv_sec, zero_extend_signed_to_ull(p_new->it_interval.tv_usec), (long long) p_new->it_value.tv_sec, zero_extend_signed_to_ull(p_new->it_value.tv_usec), p_old, sprintrc(rc)); puts("+++ exited with 0 +++"); return 0; }