3 # Copyright (C) 2016 Julien Desfossez <jdesfossez@efficios.com>
5 # SPDX-License-Identifier: GPL-2.0-only
8 TEST_DESC
="Kernel tracer - select, poll and epoll payload extraction"
10 CURDIR
=$
(dirname "$0")/
12 VALIDATE_SCRIPT
="$CURDIR/validate_select_poll_epoll.py"
15 # Only run this test on x86 and arm
16 uname
-m |
grep -E "x86|i686|arm|aarch64" >/dev
/null
2>&1
19 skip
0 "Run only on x86 and arm. Skipping all tests." $NUM_TESTS
24 # Babeltrace python bindings are required for the validation, but
25 # it is not a mandatory dependancy of the project, so fail run the
26 # without the content validation, at least we test that we are not
27 # crashing the kernel.
28 $VALIDATE_SCRIPT --help >/dev
/null
2>&1
30 echo "# Failed to run the validation script, Babeltrace Python bindings might be missing"
34 LAST_WARNING
=$
(dmesg |
grep " WARNING:" | cut
-d' ' -f1 |
tail -1)
35 LAST_OOPS
=$
(dmesg |
grep " OOPS:" | cut
-d' ' -f1 |
tail -1)
36 LAST_BUG
=$
(dmesg |
grep " BUG:" | cut
-d' ' -f1 |
tail -1)
38 # shellcheck source=../../utils/utils.sh
39 source $TESTDIR/utils
/utils.sh
41 function check_trace_content
()
43 if test $DISABLE_VALIDATE == 1; then
44 ok
0 "Validation skipped"
50 ok
0 "Validation success"
56 function test_working_cases
()
58 SESSION_NAME
="syscall_payload"
59 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
60 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
62 # arm64 does not have epoll_wait
63 uname
-m |
grep -E "aarch64" >/dev
/null
2>&1
65 SYSCALL_LIST
="select,pselect6,poll,ppoll,epoll_ctl,epoll_pwait"
67 SYSCALL_LIST
="select,pselect6,poll,ppoll,epoll_ctl,epoll_wait,epoll_pwait"
70 diag
"Working cases for select, pselect6, poll, ppoll and epoll, waiting for input"
72 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
74 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
75 add_context_kernel_ok
$SESSION_NAME channel0 pid
77 start_lttng_tracing_ok
78 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 1
81 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
82 check_trace_content
-t 1 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH"
84 destroy_lttng_session_ok
$SESSION_NAME
87 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
90 function test_timeout_cases
()
92 SESSION_NAME
="syscall_payload"
93 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
94 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
96 # arm64 does not have epoll_wait
97 uname
-m |
grep -E "aarch64" >/dev
/null
2>&1
99 SYSCALL_LIST
="select,pselect6,poll,ppoll,epoll_ctl,epoll_pwait"
101 SYSCALL_LIST
="select,pselect6,poll,ppoll,epoll_ctl,epoll_wait,epoll_pwait"
104 diag
"Timeout cases (1ms) for select, pselect6, poll, ppoll and epoll"
106 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
108 lttng_enable_kernel_syscall_ok
$SESSION_NAME "$SYSCALL_LIST"
109 add_context_kernel_ok
$SESSION_NAME channel0 pid
111 start_lttng_tracing_ok
112 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 2
113 stop_lttng_tracing_ok
115 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
116 check_trace_content
-t 2 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
118 destroy_lttng_session_ok
$SESSION_NAME
121 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
124 function test_pselect_invalid_fd
()
126 SESSION_NAME
="syscall_payload"
127 SYSCALL_LIST
="pselect6"
128 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
129 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
131 diag
"pselect with invalid FD"
133 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
135 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
136 add_context_kernel_ok
$SESSION_NAME channel0 pid
138 start_lttng_tracing_ok
139 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 3
140 stop_lttng_tracing_ok
142 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
143 check_trace_content
-t 3 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
145 destroy_lttng_session_ok
$SESSION_NAME
148 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
151 function test_big_ppoll
()
153 SESSION_NAME
="syscall_payload"
155 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
156 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
158 diag
"ppoll with 2047 FDs"
160 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
162 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
163 add_context_kernel_ok
$SESSION_NAME channel0 pid
165 start_lttng_tracing_ok
166 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 4
167 stop_lttng_tracing_ok
169 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
170 check_trace_content
-t 4 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
172 destroy_lttng_session_ok
$SESSION_NAME
175 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
178 function test_ppoll_overflow
()
180 SESSION_NAME
="syscall_payload"
182 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
183 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
185 diag
"ppoll buffer overflow, should segfault, waits for input"
187 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
189 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
190 add_context_kernel_ok
$SESSION_NAME channel0 pid
192 start_lttng_tracing_ok
193 diag
"Expect segfaults"
194 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 5
195 stop_lttng_tracing_ok
197 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
199 check_trace_content
-t 5 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
201 destroy_lttng_session_ok
$SESSION_NAME
204 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
207 function test_pselect_invalid_ptr
()
209 SESSION_NAME
="syscall_payload"
210 SYSCALL_LIST
="pselect6"
211 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
212 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
214 diag
"pselect with invalid pointer, waits for input"
216 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
218 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
219 add_context_kernel_ok
$SESSION_NAME channel0 pid
221 start_lttng_tracing_ok
222 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 6
223 stop_lttng_tracing_ok
225 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
226 check_trace_content
-t 6 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
228 destroy_lttng_session_ok
$SESSION_NAME
231 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
234 function test_ppoll_ulong_max
()
236 SESSION_NAME
="syscall_payload"
238 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
239 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
241 diag
"ppoll with ulong_max fds, waits for input"
243 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
245 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
246 add_context_kernel_ok
$SESSION_NAME channel0 pid
248 start_lttng_tracing_ok
249 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 7
250 stop_lttng_tracing_ok
252 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
253 check_trace_content
-t 7 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
255 destroy_lttng_session_ok
$SESSION_NAME
258 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
261 function test_epoll_pwait_invalid_ptr
()
263 SESSION_NAME
="syscall_payload"
264 SYSCALL_LIST
="epoll_pwait"
265 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
266 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
268 diag
"epoll_pwait with invalid pointer, waits for input"
270 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
272 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
273 add_context_kernel_ok
$SESSION_NAME channel0 pid
275 start_lttng_tracing_ok
276 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 8
277 stop_lttng_tracing_ok
279 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
280 check_trace_content
-t 8 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
282 destroy_lttng_session_ok
$SESSION_NAME
285 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
288 function test_epoll_pwait_int_max
()
290 SESSION_NAME
="syscall_payload"
291 SYSCALL_LIST
="epoll_pwait"
292 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
293 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
295 diag
"epoll_pwait with maxevents set to INT_MAX, waits for input"
297 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
299 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
300 add_context_kernel_ok
$SESSION_NAME channel0 pid
302 start_lttng_tracing_ok
303 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 9
304 stop_lttng_tracing_ok
306 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
307 check_trace_content
-t 9 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
309 destroy_lttng_session_ok
$SESSION_NAME
312 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
315 function test_ppoll_concurrent
()
317 SESSION_NAME
="syscall_payload"
319 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
320 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
322 diag
"ppoll with concurrent updates of the structure from user-space, stress test (3000 iterations), waits for input + timeout 1ms"
324 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
326 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
327 add_context_kernel_ok
$SESSION_NAME channel0 pid
329 start_lttng_tracing_ok
330 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 10
331 stop_lttng_tracing_ok
333 validate_trace
"$SYSCALL_LIST" "$TRACE_PATH"
334 check_trace_content
-t 10 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
336 destroy_lttng_session_ok
$SESSION_NAME
339 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
342 function test_epoll_pwait_concurrent
()
344 SESSION_NAME
="syscall_payload"
345 SYSCALL_LIST
="epoll_ctl,epoll_pwait"
346 TRACE_PATH
=$
(mktemp
--tmpdir -d "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
347 TEST_VALIDATION_OUTPUT_PATH
=$
(mktemp
--tmpdir -u "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
349 diag
"epoll_pwait with concurrent munmap of the buffer from user-space, should randomly segfault, run multiple times, waits for input + timeout 1ms"
351 create_lttng_session_ok
$SESSION_NAME "$TRACE_PATH"
353 lttng_enable_kernel_syscall_ok
$SESSION_NAME $SYSCALL_LIST
354 add_context_kernel_ok
$SESSION_NAME channel0 pid
356 start_lttng_tracing_ok
357 diag
"Expect segfaults"
358 for i
in $
(seq 1 100); do
359 yes |
"$CURDIR"/select_poll_epoll
--validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 11
361 stop_lttng_tracing_ok
363 # epoll_wait is not always generated in the trace (stress test)
364 validate_trace
"epoll_ctl" "$TRACE_PATH"
365 check_trace_content
-t 11 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev
/null
367 destroy_lttng_session_ok
$SESSION_NAME
370 rm -f "$TEST_VALIDATION_OUTPUT_PATH"
373 # MUST set TESTDIR before calling those functions
374 plan_tests
$NUM_TESTS
376 print_test_banner
"$TEST_DESC"
378 if [ "$(id -u)" == "0" ]; then
384 skip
$isroot "Root access is needed. Skipping all tests." $NUM_TESTS ||
386 validate_lttng_modules_present
392 test_pselect_invalid_fd
395 test_pselect_invalid_ptr
397 test_epoll_pwait_invalid_ptr
398 test_epoll_pwait_int_max
399 test_ppoll_concurrent
400 test_epoll_pwait_concurrent
404 NEW_WARNING
=$
(dmesg |
grep " WARNING:" | cut
-d' ' -f1 |
tail -1)
405 NEW_OOPS
=$
(dmesg |
grep " OOPS:" | cut
-d' ' -f1 |
tail -1)
406 NEW_BUG
=$
(dmesg |
grep " BUG:" | cut
-d' ' -f1 |
tail -1)
408 if test "$LAST_WARNING" != "$NEW_WARNING"; then
409 fail
"New WARNING generated"
411 if test "$LAST_OOPS" != "$NEW_OOPS"; then
412 fail
"New OOPS generated"
414 if test "$LAST_BUG" != "$NEW_BUG"; then
415 fail
"New BUG generated"