]> sourceware.org Git - systemtap.git/commitdiff
PR11441 - unprivileged mode test suite enhancements.
authorDave Brolley <brolley@redhat.com>
Tue, 6 Sep 2011 19:48:29 +0000 (15:48 -0400)
committerDave Brolley <brolley@redhat.com>
Tue, 6 Sep 2011 19:51:17 +0000 (15:51 -0400)
- Created a script which identifies all embedded C code in our tapset
  sources.
- Tests to ensure that calls to each function containing embedded C are
  accepted/rejected for unprivileged users, as appropriate.

testsuite/systemtap.unprivileged/embeddedc.awk [new file with mode: 0755]
testsuite/systemtap.unprivileged/unprivileged_embedded_C.exp [new file with mode: 0644]
testsuite/systemtap.unprivileged/unprivileged_probes.exp [moved from testsuite/systemtap.unprivileged/unprivileged_all.exp with 100% similarity]

diff --git a/testsuite/systemtap.unprivileged/embeddedc.awk b/testsuite/systemtap.unprivileged/embeddedc.awk
new file mode 100755 (executable)
index 0000000..cb2a5d2
--- /dev/null
@@ -0,0 +1,145 @@
+#!/bin/awk -f
+
+BEGIN {
+    isfunc = 0
+    block = 0
+    embedded = 0
+}
+
+# print the function prototype, all on one line.
+/^function/ {
+    if (block != 0 || embedded != 0) {
+       printf "Unterminated block at: %s: %d %d\n",$0,block,embedded > "/dev/stderr"
+       exit 1
+    }
+    isfunc = 1
+    unprivileged = -1
+    myproc_unprivileged = -1
+}
+
+/^function/,/\)/ {
+    # Strip characters after the ')'.
+    temp = $0
+    sub("\\).*", ")", temp)
+#    print "after stripping trailing chars: " temp
+
+    # Strip the the return type.
+    temp = gensub("^function[[:space:]]*([\\$_[:alpha:]][\\$_[:alnum:]]*)[[:space:]]*:[[:space:]]*[[:alpha:]]*",
+                 "function \\1", 1, temp)
+#    print "after stripping return type: " temp
+
+    # Strip the 'function'.
+    temp = gensub("^function[[:space:]]*", "", 1, temp)
+#    print "after stripping function: " temp
+
+    # Add the default type where it has been omitted.
+    do {
+       temp1 = temp
+       temp = gensub("([(,][[:space:]]*[\\$_[:alpha:]][\\$_[:alnum:]]*)[[:space:]]*([,)])",
+                     "\\1:long\\2", "g", temp)
+#      print "after adding a default type: " temp
+    } while (temp != temp1)
+
+    # Strip paramater names.
+    temp = gensub("[\\$_[:alpha:]][\\$_[:alnum:]]*[[:space:]]*:[[:space:]]*([[:alpha:]])",
+                 "\\1", "g", temp)
+#    print "after stripping parm names: "
+
+    printf "%s",temp
+    fflush()
+}
+
+# Beginning of an embedded C block
+(! /^.*\/\/.*%{/) && /%{/ {
+    block += 1
+    embedded += 1
+#    printf "%s",$0
+#    print ": embedded start:" block " " embedded
+}
+
+# Beginning of a preprocessor block
+(! /^.*\/\/.*%\(/) && /%\(/ {
+    block += 1
+#    printf "%s",$0
+#    print ": preprocessor start:" block " " embedded
+}
+
+# Beginning of a code block
+/^{/ {
+    block += 1
+#    printf "%s",$0
+#    print ": block start:" block " " embedded
+}
+(! /^.*\/\/.*{/) && /[^%]{/ {
+    block += 1
+#    printf "%s",$0
+#    print ": block start:" block " " embedded
+}
+
+# unprivileged?
+/\/\* unprivileged \*\// {
+    if (embedded && unprivileged != 0)
+       unprivileged = 1
+}
+/\/\* myproc-unprivileged \*\// {
+    if (embedded && myproc_unprivileged != 0)
+       myproc_unprivileged = 1
+}
+
+# Process the end of a tapset function.
+function finish_function() {
+    if (block == 0 && isfunc) {
+       if (unprivileged == 1)
+           print " ; unprivileged"
+       else if (myproc_unprivileged == 1)
+           print " ;myproc-unprivileged"
+       else if (unprivileged != -1 || myproc_unprivileged != -1)
+           print " ;privileged"
+       else
+           print " ;no embedded C"
+       fflush()
+       isfunc = 0
+    }
+}
+
+# End of an embedded C block
+(! /^.*\/\/.*%}/) && /%}/ {
+    embedded -= 1
+    block -= 1
+    if (unprivileged == -1)
+       unprivileged = 0
+    if (myproc_unprivileged == -1)
+       myproc_unprivileged = 0
+#    printf "%s",$0
+#    print ": embedded end:" block " " embedded
+    finish_function()
+}
+
+# End of a preprocessor C block
+(! /^.*\/\/.*%\)/) && /%\)/ {
+    block -= 1
+#    printf "%s",$0
+#    print ": embedded end:" block " " embedded
+    finish_function()
+}
+
+# End of a code block
+/^}/ {
+    block -= 1
+#   printf "%s",$0
+#   print ": block end:" block " " embedded
+    finish_function()
+}
+(! /^.*\/\/.*}/) && /[^%]}/ {
+    block -= 1
+#    printf "%s",$0
+#    print ": block end:" block " " embedded
+    finish_function()
+}
+
+END {
+    if (block != 0 || embedded != 0) {
+       printf "Unterminated block at EOF: %d %d\n",block,embedded > "/dev/stderr"
+       exit 1
+    }
+}
\ No newline at end of file
diff --git a/testsuite/systemtap.unprivileged/unprivileged_embedded_C.exp b/testsuite/systemtap.unprivileged/unprivileged_embedded_C.exp
new file mode 100644 (file)
index 0000000..5d1440a
--- /dev/null
@@ -0,0 +1,99 @@
+set test "unprivileged embedded C"
+
+# Add arguments to a probe type template.
+proc add_args { prototype } {
+    set call "$prototype"
+
+    # Replace long with 0
+    regsub -all "(\[(,]\[\[:space:]]*)long" $call "\\10" call
+
+    # Replace string with "0"
+    regsub -all "(\[(,]\[\[:space:]]*)string" $call "\\1\"0\"" call
+
+    return "$call"
+}
+
+# Test valid probe types
+proc test_embedded_C { use_wrapper } {
+    global prototype_info test
+
+    if { $use_wrapper } {
+       set with_wrapper " with wrapper"
+    } else {
+       set with_wrapper ""
+    }
+
+    foreach info $prototype_info {
+       verbose -log "testing $info"
+
+       # Separate the prototype and its status.
+       set tokens [split $info ";"]
+       set prototype [lindex $tokens 0]
+       set status [lindex $tokens 1]
+
+       # Test calling the function. If successful, the stap rc will be 0.
+       set call [add_args $prototype]
+       set cmd [concat [list stap -p2 --unprivileged -e "probe begin { $call }"]]
+       verbose -log "eval exec $cmd"
+       set rc [catch {eval exec $cmd} res_stap]
+       verbose -log $res_stap
+
+       # Look for a message saying that the function is not allowed for unprivileged users.
+       regexp "(\[^\[:space:](]*).*" $prototype match funcname
+       verbose -log "funcname is $funcname"
+
+       # The function '_wait_status_str' is not allowed for unprivileged but it fails with a
+       # reference to the function '_signal_name' which it calls and which is checked first.
+       if {"$funcname" == "_wait_status_str"} {
+           set funcname "_signal_name"
+       }
+       set emsg1 "semantic error: function may not be used when --unprivileged is specified: identifier '$funcname'"
+       set emsg2 "semantic error: embedded expression may not be used when --unprivileged is specified"
+       set found [expr [regexp ".*$emsg1.*" $res_stap] || [regexp ".*$emsg2.*" $res_stap]]
+
+       # Evaluate the result based upon the function's status
+       switch $status {
+           unprivileged -
+           myproc-unprivileged -
+           "no embedded C"
+           {
+               # There should be no message excluding this function
+               set passed [expr ! $found]
+           }
+           privileged
+           {
+               # There should be a message excluding this function
+               set passed $found
+           }
+       }
+
+       if {$passed} {
+           pass "$test: $status: $prototype"
+       } else {
+           fail "$test: $status: $prototype"
+       }
+    }
+}
+
+# Obtain the prototypes of all tapset functions containing embedded C code.
+set tapsetdir "$srcdir/../tapset"
+verbose -log "Looking for tapset scripts in $tapsetdir"
+set files [glob -nocomplain $tapsetdir/*.stp]
+verbose -log "Looking for tapset scripts in $tapsetdir/[exec uname -i]"
+set files [concat $files [glob -nocomplain $tapsetdir/[exec uname -i]/*.stp]]
+
+verbose -log "eval exec $srcdir/$subdir/embeddedc.awk [join $files]"
+catch {eval exec $srcdir/$subdir/embeddedc.awk [join $files]} res_stap
+set prototype_info [split $res_stap "\n"]
+
+verbose -log "prototype_info contains [llength prototype_info] items"
+if {[llength prototype_info] > 0} {
+    pass "$test: Obtain list tapset functions containing embedded C"
+} else {
+    fail "$test: Obtain list tapset functions containing embedded C"
+    untested "$test"
+    return
+}
+
+# Now run the tests
+test_embedded_C 0
This page took 0.035993 seconds and 5 git commands to generate.