File: server_args.exp

package info (click to toggle)
systemtap 5.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 47,556 kB
  • sloc: cpp: 81,117; ansic: 54,933; xml: 49,795; exp: 43,595; sh: 11,526; python: 5,003; perl: 2,252; tcl: 1,312; makefile: 1,006; javascript: 149; lisp: 105; awk: 101; asm: 91; java: 70; sed: 16
file content (250 lines) | stat: -rw-r--r-- 8,408 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
set test "Server Argument Test"
if {! [nss_p]} { unsupported $test; return }

# Each test will take 3 seconds or more due to the use of avahi to browse for
# servers, so limit iterations to some small but reasonable number.
set iterations 10

# Allow seeding the random number generator using an environment variable in
# order to facilitate reproducing a given series of tests. Otherwise seed it
# using the current time.
if [info exists env(STAP_RANDOM_SEED)] {
    set random_seed $env(STAP_RANDOM_SEED)
} else {
    set random_seed [clock seconds]
}
verbose -log "Random seed is $random_seed"
expr srand($random_seed)

proc stap_direct_and_with_client {stap options} {
    global installed_stap use_server

    # tcl's 'eval' creates a string containing the arguments and
    # recursively passes it to the tcl interpreter. Special
    # characters need to be quoted.
    regsub -all "\[\"\\\\;\]" $options {\\\0} options
    regsub -all "\[\n\]" $options {\\n} options

    # If the options contain -I/ or the equivalent, then the client will balk.
    # So test that the client balks.
    if {[regexp -- "\-I */$" $options] || [regexp -- "\-I */ " $options]} {
	set passed 0
	set fallthrough 0
	set cmd [concat stap $options $use_server]
	send_log "executing: $cmd\n"
	eval spawn $cmd
	expect {
	    -timeout 150
	    -re {^Unable to send / to the server\r\n} {
		set passed 1
	    }
	    # Some other options can cause errors which occur before the one for -I/.
	    # If one of these errors occurs, then fall through to the normal test.
	    -re {^ERROR: Safety pattern mismatch for -. parameter .*\r\n} {
		set fallthrough 1
	    }
	    -re {^.*\r\n} { exp_continue }
	    timeout { 
		kill -INT -[exp_pid] 2
	    }
	}
	catch {close}; catch {wait}
	if { $fallthrough == 0 } {
	    return $passed
	}
    }

    # Otherwise, check the that output from compiling directly and using
    # the client/server are reasonable similar.
    verbose -log "eval exec $stap $options"
    catch {eval exec $stap $options} res_stap
    verbose -log $res_stap

    # Now run it using the client
    verbose -log "eval exec $stap $use_server $options"
    catch {eval exec $stap $use_server $options} res_stap_client
    verbose -log $res_stap_client

    # Now check the output
    set skip_hostname_mode 0
    set n 0
    set expected [split $res_stap "\n"]
    set received [split $res_stap_client "\n"]
    foreach line $received {
	# Instructed to skip hostnames?
	if {$skip_hostname_mode} {
	    if {[regexp {^  \S+$} $line]} {
		verbose -log "skipping: $line"
		continue
	    } else {
		set skip_hostname_mode 0
	    }
	}
	# Ignore warnings about the domain name on the certificate not matching
	if {[regexp {^WARNING: The domain name, [^,]*, does not match the DNS name\(s\) on the server certificate:} $line]} {
	    set skip_hostname_mode 1
	    verbose -log "skipping: $line"
	    continue
	}
	set expected_line [lindex $expected $n]
	# Some messages contain the names of files or directories
	# and will be prefixed for the client.
	if {[regexp "^              (.*)" $expected_line match data]} {
            verbose -log "MATCH: $match"
            verbose -log "DATA: $data"
	    # Special characters in the regexp need to be quoted.
	    regsub -all "\[\"\\\\;\*\(\)\]" $data {\\\0} data
	    if {[regexp "^              tapset.*/$data" $line]} {
		incr n
		continue
	    }
	    if {[regexp "^              runtime.*/$data" $line]} {
		incr n
		continue
	    }
	    # Some messages contain the name of the module based on the
	    # process id.
	    if {[regexp "^              stap_\[0-9\]*" $expected_line] &&
		[regexp "^              stap_\[0-9\]*" $line]} {
		incr n
		continue
	    }
	} elseif {[regexp "^Input file '(.*)' is empty or missing." $expected_line match data]} {
	    # Special characters in the regexp need to be quoted.
	    regsub -all "\[\"\\\\;\*\]" $data {\\\0} data
	    if {[regexp "^Input file 'script.*/$data' is empty or missing." $line]} {
		incr n
		continue
	    }
	} elseif {[regexp "^Input file '(.*)' is missing." $expected_line match data]} {
	    # Special characters in the regexp need to be quoted.
	    regsub -all "\[\"\\\\;\*\]" $data {\\\0} data
	    if {[regexp "^Input file 'script.*/$data' is missing." $line]} {
		incr n
		continue
	    }
	} elseif {[regexp "^(.*/stap): (.*)" $line match data1 data2]} {
	    # Special characters in the regexp need to be quoted.
	    regsub -all "\[\"\\\\;\*\]" $data2 {\\\0} data2
	    if {[regexp "^$stap: $data2" $expected_line]} {
		incr n
		continue
	    }
	}

	# Otherwise the output must be identical.
	if {! [string equal $line $expected_line]} {
	    break
	}
	incr n
    }
    if {$n == [llength $expected] && [llength $expected] <= [llength $received]} {
	# Test passes
	return 1
    }
    # Test fails
    send_log "line [expr $n + 1]:\n"
    send_log "Expected: \"[lindex $expected $n]\"\n"
    send_log "Got     : \"$line\"\n"
    return 0
}

# ************ Start of mainline *************

# Don't attempt these tests if the client/server are not available
if {! [setup_server]} then {
    untested "$test"
    return
}

# Make sure we call the correct instance of stap
# There is a copy of stap on the PATH which always uses --use-server NOT ANY MORE!!!
#if {[installtest_p]} then {
#    # For 'make installcheck', use the installed stap
#    set stap $installed_stap
#} else {
#    # For 'make check' use stap from the build tree
#    set stap [exec pwd]/../stap
#}
set stap stap

# Test some argument strings which have failed in the past. This is useful
# for debugging a currently failing case and helps to ensure that previously
# fixed cases do not regress.

# TODO: Debug this one: "-p1 -I -e\\;/ -Dhn6 -cejijqmi0 -S3-k -"
set previously_fixed [list \
  "-p1 -I=\\w94\nbh -e -Dhfuo0iu7 -c" \
  "-p1 -I8o\\2ie -e'1\\ -D\n\" -c" \
  "-p1 -Ira\\3;c g -e0fle'qq -Dr/316k\\o8 -cjyoc\n3" \
  "-p1 -I6p3 -elc -Dqgsgv' -c" \
  "-p1 -I\"vyv;z -ej\"/3 -D/ 01qck\n -c3u55zut" \
  "-p1 -I1 -eo9e\nx047q -D9xyefk0a -cvl98/x1'i" \
  "-p1 -c; test.stp" \
  "-p1 -I4hgy96 -e5oo39p -Ddx8v -c4;" \
  "-p1 -I -esq3wors -Dz -c*eibz8h2e" \
  "-p1 -I a -em339db5 -Du2;c0ps -ch9o\\" \
  "-p1 -Ipfjps4 -ebug4dc -Du8vd fvkl -c" \
  "-p1 -I0\"nspzjyf -e5r3up8h -Dmi;ojp9m -cx;a2fat" \
  "-p1 -Iu -ek7;r -Dcu\"; -c\"hc" \
  "-p1 -Icd4fidq  m40mv -edn -D;8ha\\cjr -c1*vnq" \
  "-p1 -I;3 -er8e -D -cb6k29z" \
  "-p1 -Ircj -e -D -c\\vmww" \
  "-p1 -Illc5 -e65wof9 qr*=x7x5 -D -cgx;" \
  "-p1 -Iyaj420=3 -e\" -D -cd'5mi" \
  "-p1 -Ir -e -D29\\ -cj2szt;4" \
  "-p1 -Ibno3=b4sk -e' -Dg2-j;e -c2ijx'" \
  "-p1 -I285v7pl -eo5\\0 -D86s -c-c*v" \
  "-l syscall.open* -- -p5" \
  "-l syscall.open* -- -rfoo" \
  "-p1 -I/ 1\\nbzg3 -ebf -Do -ckrll=\\;oh -\S4" \
  "-p1 -I / 1\\nbzg3 -ebf -Do -ckrll=\\;oh -\S4" \
  "-p1 1\\nbzg3 -ebf -Do -ckrll=\\;oh -\S4 -I/" \
  "-p1 1\\nbzg3 -ebf -Do -ckrll=\\;oh -\S4 -I /" \
  "-p1 -I -e\\;/ -Dhn6 -cejijqmi0 -S3-k -" \
  "-p1 -I/ -e/ -D -c\\n1v\\;nd8 -S--" \
  "-p1 -I/ -e0xzu -Dxrk -c*sum8fe  -St546jn" \
]

set i 0
foreach options $previously_fixed {
    if {[stap_direct_and_with_client $stap $options]} {
	pass "$test $i"
    } else {
	fail "$test $i"
    }
    incr i
}

# Generate semi-random arguments containing with potential problem characters.
# Check that running systemtap with the client/server generates output
# comparable to running stap directly.
set dangerous_options [list "-I" "-e" "-D" "-c" "-S"]
# NB: Other options could be candidates here, like -r and -B, but                                   
# there stap-server imposes more restrictions than local stap, so                                   
# this simple error-matching test cannot use them.                                                  
set argchars "0123456789/;*'=-\\\"\n abcdefghijklmnopqrstuvwxyz"

for {set i 0} {$i < $iterations} {incr i} {
    verbose -log "Iteration $i"

    # First generate an argument string
    set options "-p1"
    foreach option $dangerous_options {
	set options "$options $option"
	set limit [expr int(rand() * 10)]
	for {set c 0} {$c < $limit} {incr c} {
	    set options "$options[string index $argchars [expr int(rand() * [string length $argchars])]]"
	}
    }

    # Now test it against stap and stap client
    if {[stap_direct_and_with_client $stap $options]} {
	pass "Fuzzing $test $i"
    } else {
	fail "Fuzzing $test $i"
    }
}

# Shudown the server.
shutdown_server