1 /*
2 * Check decoding of setitimer and getitimer syscalls.
3 *
4 * Copyright (c) 2015-2018 Dmitry V. Levin <ldv@strace.io>
5 * Copyright (c) 2015-2020 The strace developers.
6 * All rights reserved.
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include "tests.h"
12 #include <stdio.h>
13 #include <stdint.h>
14 #include <sys/time.h>
15 #include <unistd.h>
16 #include "scno.h"
17 #include "kernel_timeval.h"
18
19 typedef struct {
20 kernel_old_timeval_t it_interval;
21 kernel_old_timeval_t it_value;
22 } kernel_old_itimerval_t;
23
24 int
25 main(void)
26 {
27 static const kernel_old_itimerval_t new = {
28 .it_interval = { 0xc0de1, 0xc0de2 },
29 .it_value = { 0xc0de3, 0xc0de4 }
30 };
31 static const kernel_ulong_t long_timer =
32 F8ILL_KULONG_MASK | ITIMER_REAL;
33 static const kernel_ulong_t bogus_timer =
34 (kernel_ulong_t) 0xfacefeeddeadbeefULL;
35
36 TAIL_ALLOC_OBJECT_CONST_PTR(kernel_old_itimerval_t, p_old);
37 kernel_old_itimerval_t *const p_new = tail_memdup(&new, sizeof(new));
38 void *const efault = tail_alloc(sizeof(new) - 8);
39 long rc;
40
41 if (syscall(__NR_setitimer, ITIMER_REAL, p_new, NULL))
42 perror_msg_and_skip("setitimer");
43 printf("setitimer(ITIMER_REAL"
44 ", {it_interval={tv_sec=%lld, tv_usec=%llu}"
45 ", it_value={tv_sec=%lld, tv_usec=%llu}}"
46 ", NULL) = 0\n",
47 (long long) new.it_interval.tv_sec,
48 zero_extend_signed_to_ull(new.it_interval.tv_usec),
49 (long long) new.it_value.tv_sec,
50 zero_extend_signed_to_ull(new.it_value.tv_usec));
51
52 fill_memory(p_old, sizeof(*p_old));
53 if (syscall(__NR_getitimer, ITIMER_REAL, p_old))
54 perror_msg_and_skip("getitimer");
55 printf("getitimer(ITIMER_REAL"
56 ", {it_interval={tv_sec=%lld, tv_usec=%llu}"
57 ", it_value={tv_sec=%lld, tv_usec=%llu}}) = 0\n",
58 (long long) p_old->it_interval.tv_sec,
59 zero_extend_signed_to_ull(p_old->it_interval.tv_usec),
60 (long long) p_old->it_value.tv_sec,
61 zero_extend_signed_to_ull(p_old->it_value.tv_usec));
62
63 fill_memory(p_old, sizeof(*p_old));
64 syscall(__NR_setitimer, ITIMER_REAL, p_new, p_old);
65 printf("setitimer(ITIMER_REAL"
66 ", {it_interval={tv_sec=%lld, tv_usec=%llu}"
67 ", it_value={tv_sec=%lld, tv_usec=%llu}}"
68 ", {it_interval={tv_sec=%lld, tv_usec=%llu}"
69 ", it_value={tv_sec=%lld, tv_usec=%llu}}) = 0\n",
70 (long long) new.it_interval.tv_sec,
71 zero_extend_signed_to_ull(new.it_interval.tv_usec),
72 (long long) new.it_value.tv_sec,
73 zero_extend_signed_to_ull(new.it_value.tv_usec),
74 (long long) p_old->it_interval.tv_sec,
75 zero_extend_signed_to_ull(p_old->it_interval.tv_usec),
76 (long long) p_old->it_value.tv_sec,
77 zero_extend_signed_to_ull(p_old->it_value.tv_usec));
78
79 rc = syscall(__NR_getitimer, ITIMER_REAL, efault);
80 printf("getitimer(ITIMER_REAL, %p) = %s\n", efault, sprintrc(rc));
81
82 rc = syscall(__NR_setitimer, ITIMER_REAL, p_new, efault);
83 printf("setitimer(ITIMER_REAL"
84 ", {it_interval={tv_sec=%lld, tv_usec=%llu}"
85 ", it_value={tv_sec=%lld, tv_usec=%llu}}, %p) = %s\n",
86 (long long) new.it_interval.tv_sec,
87 zero_extend_signed_to_ull(new.it_interval.tv_usec),
88 (long long) new.it_value.tv_sec,
89 zero_extend_signed_to_ull(new.it_value.tv_usec),
90 efault, sprintrc(rc));
91
92 rc = syscall(__NR_setitimer, ITIMER_REAL, efault, p_old);
93 printf("setitimer(ITIMER_REAL, %p, %p) = %s\n",
94 efault, p_old, sprintrc(rc));
95
96 fill_memory(p_old, sizeof(*p_old));
97 rc = syscall(__NR_setitimer, long_timer, p_new, p_old);
98 printf("setitimer(ITIMER_REAL"
99 ", {it_interval={tv_sec=%lld, tv_usec=%llu}"
100 ", it_value={tv_sec=%lld, tv_usec=%llu}}"
101 ", {it_interval={tv_sec=%lld, tv_usec=%llu}"
102 ", it_value={tv_sec=%lld, tv_usec=%llu}}) = %s\n",
103 (long long) new.it_interval.tv_sec,
104 zero_extend_signed_to_ull(new.it_interval.tv_usec),
105 (long long) new.it_value.tv_sec,
106 zero_extend_signed_to_ull(new.it_value.tv_usec),
107 (long long) p_old->it_interval.tv_sec,
108 zero_extend_signed_to_ull(p_old->it_interval.tv_usec),
109 (long long) p_old->it_value.tv_sec,
110 zero_extend_signed_to_ull(p_old->it_value.tv_usec),
111 sprintrc(rc));
112
113 fill_memory(p_old, sizeof(*p_old));
114 rc = syscall(__NR_getitimer, long_timer, p_old);
115 printf("getitimer(ITIMER_REAL"
116 ", {it_interval={tv_sec=%lld, tv_usec=%llu}"
117 ", it_value={tv_sec=%lld, tv_usec=%llu}}) = %s\n",
118 (long long) p_old->it_interval.tv_sec,
119 zero_extend_signed_to_ull(p_old->it_interval.tv_usec),
120 (long long) p_old->it_value.tv_sec,
121 zero_extend_signed_to_ull(p_old->it_value.tv_usec),
122 sprintrc(rc));
123
124 rc = syscall(__NR_setitimer, bogus_timer, p_new, p_old);
125 printf("setitimer(%#x /* ITIMER_??? */"
126 ", {it_interval={tv_sec=%lld, tv_usec=%llu}"
127 ", it_value={tv_sec=%lld, tv_usec=%llu}}, %p) = %s\n",
128 (int) bogus_timer,
129 (long long) new.it_interval.tv_sec,
130 zero_extend_signed_to_ull(new.it_interval.tv_usec),
131 (long long) new.it_value.tv_sec,
132 zero_extend_signed_to_ull(new.it_value.tv_usec),
133 p_old, sprintrc(rc));
134
135 rc = syscall(__NR_getitimer, bogus_timer, p_old);
136 printf("getitimer(%#x /* ITIMER_??? */, %p) = %s\n",
137 (int) bogus_timer, p_old, sprintrc(rc));
138
139 if (F8ILL_KULONG_SUPPORTED) {
140 const kernel_ulong_t ill_new = f8ill_ptr_to_kulong(p_new);
141 const kernel_ulong_t ill_old = f8ill_ptr_to_kulong(p_old);
142
143 rc = syscall(__NR_setitimer, long_timer, ill_new, ill_old);
144 printf("setitimer(ITIMER_REAL, %#llx, %#llx) = %s\n",
145 (unsigned long long) ill_new,
146 (unsigned long long) ill_old,
147 sprintrc(rc));
148
149 rc = syscall(__NR_getitimer, long_timer, ill_old);
150 printf("getitimer(ITIMER_REAL, %#llx) = %s\n",
151 (unsigned long long) ill_old, sprintrc(rc));
152 }
153
154 p_new->it_interval.tv_sec = 0xdeadbeefU;
155 p_new->it_interval.tv_usec = 0xfacefeedU;
156 p_new->it_value.tv_sec =
157 (typeof(p_new->it_value.tv_sec)) 0xcafef00ddeadbeefLL;
158 p_new->it_value.tv_usec =
159 (typeof(p_new->it_value.tv_usec)) 0xbadc0dedfacefeedLL;
160
161 rc = syscall(__NR_setitimer, ITIMER_REAL, p_new, p_old);
162 printf("setitimer(ITIMER_REAL"
163 ", {it_interval={tv_sec=%lld, tv_usec=%llu}"
164 ", it_value={tv_sec=%lld, tv_usec=%llu}}, %p) = %s\n",
165 (long long) p_new->it_interval.tv_sec,
166 zero_extend_signed_to_ull(p_new->it_interval.tv_usec),
167 (long long) p_new->it_value.tv_sec,
168 zero_extend_signed_to_ull(p_new->it_value.tv_usec),
169 p_old, sprintrc(rc));
170
171 puts("+++ exited with 0 +++");
172 return 0;
173 }