]> sourceware.org Git - systemtap.git/blob - testsuite/systemtap.unprivileged/unprivileged_probes.exp
372cb098cf8b7921facc847329bd4408b94b2d73
[systemtap.git] / testsuite / systemtap.unprivileged / unprivileged_probes.exp
1 set test "unprivileged probes"
2
3 set exepath "foo"
4 set sopath "libfoo.so"
5
6 # These probe types should be acceptable for unprivileged users
7 set unrestricted_probe_types [list \
8 "begin" \
9 "begin(number)" \
10 "end" \
11 "end(number)" \
12 "error" \
13 "error(number)" \
14 "never" \
15 "process.begin" \
16 "process.end" \
17 "process.function(number)" \
18 "process.function(number).call" \
19 "process.function(number).inline" \
20 "process.function(number).return" \
21 "process.function(number).exported" \
22 "process.function(string)" \
23 "process.function(string).call" \
24 "process.function(string).inline" \
25 "process.function(string).label(string)" \
26 "process.function(string).return" \
27 "process.function(string).exported" \
28 "process.plt" \
29 "process.plt.statement(number)" \
30 "process.plt(string)" \
31 "process.plt(string).statement(number)" \
32 "process.library(string).function(number)" \
33 "process.library(string).function(number).call" \
34 "process.library(string).function(number).inline" \
35 "process.library(string).function(number).return" \
36 "process.library(string).function(number).exported" \
37 "process.library(string).function(string)" \
38 "process.library(string).function(string).call" \
39 "process.library(string).function(string).inline" \
40 "process.library(string).function(string).return" \
41 "process.library(string).function(string).exported" \
42 "process.library(string).function(string).label(string)" \
43 "process.library(string).plt" \
44 "process.library(string).plt.statement(number)" \
45 "process.library(string).plt(string)" \
46 "process.library(string).plt(string).statement(number)" \
47 "process.library(string).mark(string)" \
48 "process.library(string).provider(string).mark(string)" \
49 "process.library(string).statement(number)" \
50 "process.library(string).statement(string)" \
51 "process.provider(string).mark(string)" \
52 "process.mark(string)" \
53 "process.statement(number)" \
54 "process.statement(string)" \
55 "process.syscall" \
56 "process.syscall.return" \
57 "process.thread.begin" \
58 "process.thread.end" \
59 "process(number).begin" \
60 "process(number).end" \
61 "process(number).statement(number).absolute" \
62 "process(number).statement(number).absolute.return" \
63 "process(number).syscall" \
64 "process(number).syscall.return" \
65 "process(number).thread.begin" \
66 "process(number).thread.end" \
67 "process(string).begin" \
68 "process(string).end" \
69 "process(string).function(number)" \
70 "process(string).function(number).call" \
71 "process(string).function(number).inline" \
72 "process(string).function(number).return" \
73 "process(string).function(number).exported" \
74 "process(string).function(string)" \
75 "process(string).function(string).call" \
76 "process(string).function(string).inline" \
77 "process(string).function(string).label(string)" \
78 "process(string).function(string).return" \
79 "process(string).function(string).exported" \
80 "process(string).library(string).function(number)" \
81 "process(string).library(string).function(number).call" \
82 "process(string).library(string).function(number).inline" \
83 "process(string).library(string).function(number).return" \
84 "process(string).library(string).function(number).exported" \
85 "process(string).library(string).function(string)" \
86 "process(string).library(string).function(string).call" \
87 "process(string).library(string).function(string).inline" \
88 "process(string).library(string).function(string).return" \
89 "process(string).library(string).function(string).exported" \
90 "process(string).library(string).function(string).label(string)" \
91 "process(string).library(string).mark(string)" \
92 "process(string).library(string).provider(string).mark(string)" \
93 "process(string).library(string).statement(number)" \
94 "process(string).library(string).statement(string)" \
95 "process(string).library(string).plt" \
96 "process(string).library(string).plt.statement(number)" \
97 "process(string).library(string).plt(string)" \
98 "process(string).library(string).plt(string).statement(number)" \
99 "process(string).mark(string)" \
100 "process(string).provider(string).mark(string)" \
101 "process(string).statement(number)" \
102 "process(string).statement(string)" \
103 "process(string).plt" \
104 "process(string).plt.statement(number)" \
105 "process(string).plt(string)" \
106 "process(string).plt(string).statement(number)" \
107 "process(string).syscall" \
108 "process(string).syscall.return" \
109 "process(string).thread.begin" \
110 "process(string).thread.end" \
111 "timer.hz(number)" \
112 "timer.jiffies(number)" \
113 "timer.jiffies(number).randomize(number)" \
114 "timer.ms(number)" \
115 "timer.ms(number).randomize(number)" \
116 "timer.msec(number)" \
117 "timer.msec(number).randomize(number)" \
118 "timer.ns(number)" \
119 "timer.ns(number).randomize(number)" \
120 "timer.nsec(number)" \
121 "timer.nsec(number).randomize(number)" \
122 "timer.s(number)" \
123 "timer.s(number).randomize(number)" \
124 "timer.sec(number)" \
125 "timer.sec(number).randomize(number)" \
126 "timer.us(number)" \
127 "timer.us(number).randomize(number)" \
128 "timer.usec(number)" \
129 "timer.usec(number).randomize(number)" \
130 ]
131
132 # These probes should not be acceptable to pass 2 for unprivileged users
133 set restricted_probe_types [list \
134 "process(string).insn" \
135 "kernel.data(number).length(number).rw" \
136 "kernel.data(number).length(number).write" \
137 "kernel.data(number).rw" \
138 "kernel.data(number).write" \
139 "kernel.data(string).rw" \
140 "kernel.data(string).write" \
141 "kernel.function(number)" \
142 "kernel.function(number).call" \
143 "kernel.function(number).inline" \
144 "kernel.function(number).return" \
145 "kernel.function(number).exported" \
146 "kernel.function(number).return.maxactive(number)" \
147 "kernel.function(string)" \
148 "kernel.function(string).call" \
149 "kernel.function(string).inline" \
150 "kernel.function(string).label(string)" \
151 "kernel.function(string).return" \
152 "kernel.function(string).exported" \
153 "kernel.function(string).return.maxactive(number)" \
154 "kernel.mark(string)" \
155 "kernel.mark(string).format(string)" \
156 "kernel.statement(number)" \
157 "kernel.statement(number).absolute" \
158 "kernel.statement(string)" \
159 "kernel.trace(string)" \
160 "kprobe.function(string)" \
161 "kprobe.function(string).return" \
162 "kprobe.function(string).return.maxactive(number)" \
163 "kprobe.module(string).function(string)" \
164 "kprobe.module(string).function(string).return" \
165 "kprobe.module(string).function(string).return.maxactive(number)" \
166 "kprobe.statement(number).absolute" \
167 "module(string).function(number)" \
168 "module(string).function(number).call" \
169 "module(string).function(number).inline" \
170 "module(string).function(number).return" \
171 "module(string).function(number).exported" \
172 "module(string).function(number).return.maxactive(number)" \
173 "module(string).function(string)" \
174 "module(string).function(string).call" \
175 "module(string).function(string).inline" \
176 "module(string).function(string).label(string)" \
177 "module(string).function(string).return" \
178 "module(string).function(string).exported" \
179 "module(string).function(string).return.maxactive(number)" \
180 "module(string).statement(number)" \
181 "module(string).statement(string)" \
182 "perf.type(number).config(number)" \
183 "perf.type(number).config(number).sample(number)" \
184 "process(number).insn" \
185 "process(number).insn.block" \
186 "process(string).insn.block" \
187 "procfs.read" \
188 "procfs.write" \
189 "procfs.read.maxsize(number)" \
190 "procfs.umask(number).read" \
191 "procfs.umask(number).read.maxsize(number)" \
192 "procfs.umask(number).write" \
193 "procfs(string).read" \
194 "procfs(string).read.maxsize(number)" \
195 "procfs(string).write" \
196 "procfs(string).umask(number).read" \
197 "procfs(string).umask(number).read.maxsize(number)" \
198 "procfs(string).umask(number).write" \
199 "timer.profile" \
200 ]
201
202 # Add arguments to a probe type template.
203 proc add_args { probe_type } {
204 global exepath sopath
205 global addr_of_bar addr_of_libfoofunc
206
207 set probe "$probe_type"
208
209 # Replace "hz(number)" with "hz(1000)"
210 regsub -all "hz\\(number\\)" $probe "hz(1000)" probe
211 # Replace "ns(number)" with "ns(100000)"
212 regsub -all "ns\\(number\\)" $probe "ns(100000)" probe
213 # Replace "nsec(number)" with "nsec(100000)"
214 regsub -all "nsec\\(number\\)" $probe "nsec(100000)" probe
215 # Replace "us(number)" with "us(100)"
216 regsub -all "us\\(number\\)" $probe "us(100)" probe
217 # Replace "usec(number)" with "usec(100)"
218 regsub -all "usec\\(number\\)" $probe "usec(100)" probe
219
220 # Replace "library(string).function(string).inline" with "library(string).function("ilibfoofunc").inline"
221 regsub -all "library\\(string\\).function\\(string\\).inline" $probe "library(string).function(\"ilibfoofunc\").inline" probe
222
223 # Replace "function(string).inline" with "function("ibar").inline"
224 regsub -all "function\\(string\\).inline" $probe "function(\"ibar\").inline" probe
225
226 # Replace "library(string).function(string)" with "library(string.function("libfoofunc")"
227 regsub -all "library\\(string\\).function\\(string\\)" $probe "library(string).function(\"libfoofunc\")" probe
228 # Replace "library(string).function(number)" with "library(string).function($addr_of_libfoofunc)"
229 regsub -all "library\\(string\\).function\\(number\\)" $probe "library(string).function($addr_of_libfoofunc)" probe
230
231 # Replace "function(string)" with "function("bar")"
232 regsub -all "function\\(string\\)" $probe "function(\"bar\")" probe
233 # Replace "function(number)" with "function($addr_of_bar)"
234 regsub -all "function\\(number\\)" $probe "function($addr_of_bar)" probe
235
236 # Replace "label(string)" with "label("a")"
237 regsub -all "label\\(string\\)" $probe "label(\"a\")" probe
238
239 # Replace "library(string).mark(string)" with "library(string).mark("libfoofunc_enter")"
240 regsub -all "library\\(string\\).mark\\(string\\)" $probe "library(string).mark(\"libfoofunc_enter\")" probe
241 # Replace "library(string).provider(string).mark(string)" with "library(string).provider(string).mark("libfoofunc_enter")"
242 regsub -all "library\\(string\\).provider\\(string\\).mark\\(string\\)" $probe "library(string).provider(string).mark(\"libfoofunc_enter\")" probe
243 # Replace "mark(string)" with "mark("main_enter")"
244 regsub -all "mark\\(string\\)" $probe "mark(\"main_enter\")" probe
245
246 # Replace "library(string).statement(number)" with "library(string).statement($addr_of_libfoofunc)"
247 regsub -all "library\\(string\\).statement\\(number\\)" $probe "library(string).statement($addr_of_libfoofunc)" probe
248 # Replace "library(string).statement(string)" with "library(string).statement("libfoofunc@libfoo.c:*")"
249 regsub -all "library\\(string\\).statement\\(string\\)" $probe "library(string).statement(\"libfoofunc@libfoo.c:*\")" probe
250
251 # Replace "statement(number)" with "statement($addr_of_bar)"
252 regsub -all "statement\\(number\\)" $probe "statement($addr_of_bar)" probe
253 # Replace "statement(string)" with "statement("bar@foo.c:*")"
254 regsub -all "statement\\(string\\)" $probe "statement(\"bar@foo.c:*\")" probe
255
256 # Replace "library(string)" with "library("$sopath")"
257 regsub -all "library\\(string\\)" $probe "library(\"$sopath\")" probe
258
259 # Replace "provider(string)" with "provider("_test_")"
260 regsub -all "provider\\(string\\)" $probe "provider(\"_test_\")" probe
261
262 # Replace plt with plt("*") (all shlib calls)
263 regsub -all "plt\\(string\\)" $probe "plt(\"*\")" probe
264
265 # Replace "(number)" with "(10)"
266 regsub -all "\\(number\\)" $probe "(10)" probe
267 # Replace "(string)" with "(\"$exepath\")"
268 regsub -all "\\(string\\)" $probe "(\"./$exepath\")" probe
269
270 return "$probe"
271 }
272
273 # Add required extra options according to the probe type.
274 proc extra_options { probe_type } {
275 global exepath
276
277 if {[regexp "^process" $probe_type] ||
278 [regexp "^end" $probe_type] ||
279 [regexp "^error" $probe_type]} {
280 return "-c ./$exepath"
281 }
282 return ""
283 }
284
285 # Test unrestricted probe types
286 proc test_unrestricted_probes { privilege } {
287 global unrestricted_probe_types tested allowed test
288
289 # Test using --unprivileged and --privilege=stapusr. They should be equivalent
290 set stapusr_options [list --unprivileged --privilege=stapusr ]
291 # Test using no option and --privilege=stapdev. They should be equivalent
292 set stapdev_options [list "" --privilege=stapdev ]
293 # Alternate use of additional settings (e.g. use_alias)
294 set no_yes [list 0 1]
295
296 set selector 0
297 foreach probe_type $unrestricted_probe_types {
298 switch $privilege {
299 stapusr {
300 set option [lindex $stapusr_options $selector]
301 }
302 stapdev {
303 set option [lindex $stapdev_options $selector]
304 }
305 default {
306 set option "--privilege=$privilege"
307 }
308 }
309 set use_alias [lindex $no_yes $selector]
310
311 # There are currently some known and expected failures
312 switch $probe_type {
313 process.library(string).function(number).inline -
314 process(string).library(string).function(number).inline -
315 process.function(number).inline -
316 process(string).function(number).inline
317 {
318 setup_kfail GCC *-*-*
319 }
320 }
321
322 # Test the probe type. If successful, the stap rc will be 0.
323 set probe [add_args $probe_type]
324
325 if { $use_alias } {
326 set with_alias " with alias"
327 set cmd [concat [list stap -p2 $option -e "probe myalias = $probe { println (\"Hello\"); exit (); } probe myalias {}"] [extra_options $probe_type]]
328 } else {
329 set with_alias ""
330 set cmd [concat [list stap -p2 $option -e "probe $probe { println (\"Hello\"); exit (); }"] [extra_options $probe_type]]
331 }
332
333 verbose -log "eval exec $cmd"
334 if {! [catch {eval exec $cmd} res_stap] == $allowed($probe_type,$privilege)} {
335 verbose -log $res_stap
336 pass "$test: $option $probe_type$with_alias"
337 } else {
338 verbose -log $res_stap
339 fail "$test: $option $probe_type$with_alias"
340 }
341
342 # Indicate that this probe type has been tested
343 set tested($probe_type) 1
344
345 set selector [expr ($selector + 1) % 2]
346 }
347 }
348
349 # Test restricted probe types
350 proc test_restricted_probes { privilege } {
351 global restricted_probe_types tested allowed test
352
353 set error_regexp1 ".*semantic error: probe point is not allowed for --privilege=stapusr.*"
354
355 # Test using --unprivileged and --privilege=stapusr. They should be equivalent
356 set stapusr_options [list --unprivileged --privilege=stapusr ]
357 # Test using no option and --privilege=stapdev. They should be equivalent
358 set stapdev_options [list "" --privilege=stapdev ]
359 # Alternate use of additional settings (e.g. use_alias)
360 set no_yes [list 0 1]
361
362 set selector 0
363 foreach probe_type $restricted_probe_types {
364 switch $privilege {
365 stapusr {
366 set option [lindex $stapusr_options $selector]
367 }
368 stapdev {
369 set option [lindex $stapdev_options $selector]
370 }
371 default {
372 set option "--privilege=$privilege"
373 }
374 }
375 set use_alias [lindex $no_yes $selector]
376
377 # Test the probe type. Each should fail with the expected message.
378 set probe [add_args $probe_type]
379 if { $use_alias } {
380 set with_alias " with alias"
381 set cmd [list stap $option -p2 -e "probe myalias = $probe {} probe myalias {}" ]
382 } else {
383 set with_alias ""
384 set cmd [list stap $option -p2 -e "probe $probe {}" ]
385 }
386 verbose -log "eval exec $cmd"
387 catch {eval exec $cmd} res_stap
388 verbose -log $res_stap
389 if {! [regexp $error_regexp1 $res_stap] == $allowed($probe_type,$privilege)} {
390 pass "$test: $option $probe_type$with_alias"
391 } else {
392 fail "$test: $option $probe_type$with_alias"
393 }
394
395 # Indicate that this probe type has been tested
396 set tested($probe_type) 1
397
398 set selector [expr ($selector + 1) % 2]
399 }
400 }
401
402 # Need to build a user shared library.
403 set libflags [sdt_includes]
404 set libflags "$libflags additional_flags=-g"
405 set libflags "$libflags additional_flags=-O"
406 set libflags "$libflags additional_flags=-Wall"
407 set libflags "$libflags additional_flags=-Werror"
408 set libflags "$libflags additional_flags=-I."
409 set libflags "$libflags additional_flags=-shared"
410 set libflags "$libflags additional_flags=-fPIC"
411 set res [target_compile $srcdir/$subdir/libfoo.c $sopath executable $libflags ]
412 if { $res == "" } {
413 pass "$test library compile"
414 } else {
415 fail "$test library compile: $res"
416 untested "$test Tests"
417 return
418 }
419
420 # Need to build a user application
421 set exeflags "additional_flags=-g"
422 set exeflags "$exeflags additional_flags=-O"
423 set exeflags "$exeflags additional_flags=-lpthread"
424 set exeflags "$exeflags [sdt_includes]"
425 set exeflags "$exeflags additional_flags=-Wl,-rpath,[pwd]"
426 set exeflags "$exeflags additional_flags=-L[pwd] additional_flags=-lfoo"
427 set exeflags "$exeflags compiler=gcc"
428 # ppc64 needs a more restrictive constraint for the probe args
429 if {[regexp "^(x86_64|i.86)$" $::tcl_platform(machine)] == 0} {
430 set exeflags "$exeflags additional_flags=-DSTAP_SDT_ARG_CONSTRAINT=nr"
431 }
432 set res [target_compile $srcdir/systemtap.unprivileged/foo.c $exepath executable "$exeflags"]
433 if { $res == "" } {
434 pass "$test exe compile"
435 } else {
436 fail "$test exe compile: $res"
437 untested "$test Tests"
438 return
439 }
440
441 # Extract needed addresses. Note, some architectures add a '.' to the
442 # function name, so match that optionally.
443 set addr_of_bar [exec objdump -d $exepath | awk {/<\.?bar>:/ { printf "0x%s\n",$1 }}]
444 verbose -log "addr_of_bar: $addr_of_bar"
445 set addr_of_libfoofunc [exec objdump -d $sopath | awk {/<\.?libfoofunc>:/ { printf "0x%s\n",$1 }}]
446 verbose -log "addr_of_libfoofunc: $addr_of_libfoofunc"
447
448 # Obtain a list of all supported probe types from stap
449 verbose -log "eval exec stap --dump-probe-types"
450 catch {eval exec stap --dump-probe-types} res_stap
451 set all_probe_types [split $res_stap "\n"]
452
453 # Initialize each probe type to untested
454 foreach probe_type $all_probe_types {
455 verbose -log $probe_type
456 set tested($probe_type) 0
457 }
458 if {[llength all_probe_types] > 0} {
459 pass "$test: Obtain list of supported probe types"
460 } else {
461 fail "$test: Obtain list of supported probe types"
462 untested "$test Tests"
463 return
464 }
465
466 # Initialize the expected result of running each kind of probe type with various privilege levels.
467 foreach probe_type $unrestricted_probe_types {
468 set allowed($probe_type,stapusr) 1
469 set allowed($probe_type,stapsys) 1
470 set allowed($probe_type,stapdev) 1
471 }
472 foreach probe_type $restricted_probe_types {
473 set allowed($probe_type,stapusr) 0
474 set allowed($probe_type,stapsys) 1
475 set allowed($probe_type,stapdev) 1
476 }
477
478 # Now run the tests
479 test_unrestricted_probes stapusr
480 test_unrestricted_probes stapsys
481 #test_unrestricted_probes stapdev
482 test_restricted_probes stapusr
483 test_restricted_probes stapsys
484 #test_restricted_probes stapdev
485
486 # Generate a failure for each untested probe type
487 foreach probe_type $all_probe_types {
488 set status $tested($probe_type)
489 if {$status != 0} {
490 pass "$test: tested: $probe_type"
491 } else {
492 fail "$test: not tested: $probe_type"
493 }
494 }
495
496 # Cleanup
497 catch {exec rm -f foo}
498 catch {exec rm -f libfoo.so}
This page took 0.059792 seconds and 4 git commands to generate.