File: server_privilege.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 (367 lines) | stat: -rw-r--r-- 11,064 bytes parent folder | download | duplicates (5)
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
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
# Let's try testing with optional users that only have certain
# privileges. This will allow us to do more privilege/signing
# testing.

set test "server_privilege"
if {! [installtest_p]} { untested $test; return }
if {! [nss_p]} { untested "$test (no NSS)"; return }

# Note we have to be root.
set effective_uid [exec /usr/bin/id -u]
if {$effective_uid != 0} { untested "$test (must be root)"; return }

proc compile_with_privilege { test_name privilege script } {
    global server_spec srcdir

    set cmd [concat stap -p4 $privilege --use-server=$server_spec $script ]
    send_log "executing: $cmd\n"
    set failed 1
    set module_name ''
    eval spawn $cmd
    expect {
	-timeout 150
	-re {^stap_[^ \t\r\n]*\.ko\r\n} {
	    set module_name [string trim "$expect_out(0,string)" \r\n]
	    set failed 0
	    exp_continue
	}
	-re {^.*\r\n} { exp_continue }
	timeout { 
	    kill -INT -[exp_pid] 2
	}
    }
    catch {close}
    set rc [wait -i $spawn_id]
    set rc [lindex $rc 3]
    set module_exists 0
    set subtest "module compile"
    if {$rc == 0 && $failed == 0 && [string length $module_name]} {
	pass "$test_name ($subtest)"

	# Make sure that the module and module signature were
	# returned. The module signature isn't required for 'stapdev'
	# privilege.
	if { $privilege eq "--privilege=stapdev" } {
	    set subtest "module exists"
	    if {[file exists $module_name]} {
		set module_exists 1
		pass "$test_name ($subtest)"
	    } else {
		fail "$test_name ($subtest)"
	    }
	} else {
	    set subtest "module and signature exist"
	    set module_sig "${module_name}.sgn"
	    if {[file exists $module_name] && [file exists $module_sig] } {
		set module_exists 1
		pass "$test_name ($subtest)"
	    } else {
		fail "$test_name ($subtest)"
	    }
	}
    } else {
	fail "$test_name ($subtest)"
    }
    return [list $module_exists $module_name]
}

# If we don't have any of the optional users, we could just quit. But,
# we'll go on and make sure the module compilation works.

# Now start our own server.
if {! [setup_server]} {
    untested "$test (server start failure)"
    return
}

## We only want to change the system's trusted signer list in our mount
## namespace, not in the real system.
set subtest "adding trusted signer"
set cmd "stap --trust-servers=signer,no-prompt --use-server=$server_spec"
lassign [server_ns_as_root $cmd] rc output
if {$rc == 0} {
    pass "$test - $subtest"
} else {
    fail "$test - $subtest"
}

# OK, now we've got a server. Use it to compile an unprivileged module
set subtest "unprivileged compile"
set full_test "$test - $subtest"
lassign [compile_with_privilege $full_test "--unprivileged" \
	     $srcdir/systemtap.server/hello.stp] module_exists module_name

# Make sure we can load the module. This will verify that the
# signature is correct and trusted.
if {$module_exists} {
    set module_path [exec pwd]/$module_name
    set unprivileged_module_path $module_path

    # All the users should be able to load this module.
    set subtest "stapusr unprivileged module run"
    set cmd "staprun $module_path"
    if {$systemtap_stapusr_user_exists} {
	lassign [server_ns_as_user "stapusr" $cmd] rc output
	if {$rc == 0} {
	    pass "$test - $subtest"
	} else {
	    fail "$test - $subtest"
	}
    } else {
	untested "$test - $subtest"
    }
    set subtest "stapsys unprivileged module run"
    if {$systemtap_stapsys_user_exists} {
	lassign [server_ns_as_user "stapsys" $cmd] rc output
	if {$rc == 0} {
	    pass "$test - $subtest"
	} else {
	    fail "$test - $subtest"
	}
    } else {
	untested "$test - $subtest"
    }
    set subtest "stapdev unprivileged module run"
    if {$systemtap_stapdev_user_exists} {
	lassign [server_ns_as_user "stapdev" $cmd] rc output
	if {$rc == 0} {
	    pass "$test - $subtest"
	} else {
	    fail "$test - $subtest"
	}
    } else {
	untested "$test - $subtest"
    }
}

# Now compile a module using '--privilege=stapusr'. This should be the
# same thing as '--unprivileged'.
set subtest "stapusr privilege compile"
set full_test "$test - $subtest"
lassign [compile_with_privilege $full_test "--privilege=stapusr" \
	     $srcdir/systemtap.server/test.stp] module_exists module_name

# Make sure we can load the module. This will verify that the
# signature is correct and trusted.
if {$module_exists} {
    set module_path [exec pwd]/$module_name
    set stapusr_module_path $module_path

    # All the users should be able to load this module.
    set subtest "stapusr --privilege=stapusr module run"
    set cmd "staprun $module_path"
    if {$systemtap_stapusr_user_exists} {
	lassign [server_ns_as_user "stapusr" $cmd] rc output
	if {$rc == 0} {
	    pass "$test - $subtest"
	} else {
	    fail "$test - $subtest"
	}
    } else {
	untested "$test - $subtest"
    }
    set subtest "stapsys --privilege=stapusr module run"
    if {$systemtap_stapsys_user_exists} {
	lassign [server_ns_as_user "stapsys" $cmd] rc output
	if {$rc == 0} {
	    pass "$test - $subtest"
	} else {
	    fail "$test - $subtest"
	}
    } else {
	untested "$test - $subtest"
    }
    set subtest "stapdev --privilege=stapusr module run"
    if {$systemtap_stapdev_user_exists} {
	lassign [server_ns_as_user "stapdev" $cmd] rc output
	if {$rc == 0} {
	    pass "$test - $subtest"
	} else {
	    fail "$test - $subtest"
	}
    } else {
	untested "$test - $subtest"
    }
}

# Now compile a module using '--privilege=stapsys'.
set subtest "stapsys privilege compile"
set full_test "$test - $subtest"
lassign [compile_with_privilege $full_test "--privilege=stapsys" \
	     $srcdir/systemtap.server/hello.stp ] module_exists module_name

# Make sure we can load the module. This will verify that the
# signature is correct and trusted.
if {$module_exists} {
    set module_path [exec pwd]/$module_name
    # Only the stapsys and stapdev users should be able to load this
    # module.
    set subtest "stapusr --privilege=stapsys module run"
    set cmd "staprun $module_path"
    if {$systemtap_stapusr_user_exists} {
	lassign [server_ns_as_user "stapusr" $cmd] rc output
	if {$rc == 0} {
	    fail "$test - $subtest"
	} else {
	    pass "$test - $subtest"
	}
    } else {
	untested "$test - $subtest"
    }
    set subtest "stapsys --privilege=stapsys module run"
    if {$systemtap_stapsys_user_exists} {
	lassign [server_ns_as_user "stapsys" $cmd] rc output
	if {$rc == 0} {
	    pass "$test - $subtest"
	} else {
	    fail "$test - $subtest"
	}
    } else {
	untested "$test - $subtest"
    }
    set subtest "stapdev --privilege=stapsys module run"
    if {$systemtap_stapdev_user_exists} {
	lassign [server_ns_as_user "stapdev" $cmd] rc output
	if {$rc == 0} {
	    pass "$test - $subtest"
	} else {
	    fail "$test - $subtest"
	}
    } else {
	untested "$test - $subtest"
    }
}

# Now compile a module using '--privilege=stapdev'. Note that
# 'stapdev' compiles don't need a module signature.
set subtest "stapdev privilege compile"
set full_test "$test - $subtest"
lassign [compile_with_privilege $full_test "--privilege=stapdev" \
	     $srcdir/systemtap.server/hello.stp ] module_exists module_name

# Make sure we can load the module.
if {$module_exists} {
    set module_path [exec pwd]/$module_name
    # Only the stapdev user should be able to load this module.
    set subtest "stapusr --privilege=stapdev module run"
    set cmd "staprun $module_path"
    if {$systemtap_stapusr_user_exists} {
	lassign [server_ns_as_user "stapusr" $cmd] rc output
	if {$rc == 0} {
	    fail "$test - $subtest"
	} else {
	    pass "$test - $subtest"
	}
    } else {
	untested "$test - $subtest"
    }
    set subtest "stapsys --privilege=stapdev module run"
    if {$systemtap_stapsys_user_exists} {
	lassign [server_ns_as_user "stapsys" $cmd] rc output
	if {$rc == 0} {
	    fail "$test - $subtest"
	} else {
	    pass "$test - $subtest"
	}
    } else {
	untested "$test - $subtest"
    }
    set subtest "stapdev --privilege=stapdev module run"
    if {$systemtap_stapdev_user_exists} {
	lassign [server_ns_as_user "stapdev" $cmd] rc output
	if {$rc == 0} {
	    pass "$test - $subtest"
	} else {
	    fail "$test - $subtest"
	}
    } else {
	untested "$test - $subtest"
    }
}

# Let's try changing the module and signature file and make sure the
# verifcation fails. There isn't any point in trying this if we don't
# have the modules we need or the 'stapusr' or 'stapsys' optional
# users don't exist.
set subtest "module verification"
if {([info exists unprivileged_module_path]
     && [info exists stapusr_module_path])
    && ($systemtap_stapusr_user_exists || $systemtap_stapsys_user_exists)} {

    # Use the shell to change the signature. This writes
    # 0xdeadbeef at byte 10. (We could probably do this in tcl
    # with 'binary format' and 'binary scan', but this was
    # easier.
    set rc 1
    set unprivileged_module_sig_path "${unprivileged_module_path}.sgn"
    if {$rc == 0} {
	set cmd {printf '\\xdeadbeef' | dd of=${unprivileged_module_sig_path} bs=1 seek=10 conv=notrunc}
	verbose -log "running: [subst $cmd]"
	set rc 0
	if {[catch {eval exec $cmd} output]} {
	    # non-zero exit status, get it:
	    if {[lindex $::errorCode 0] eq "CHILDSTATUS"} {
		set rc [lindex $::errorCode 2]
	    }
	}
	if {$rc != 0} {
	    verbose -log "$output"
	    fail "$test - $subtest (file change)"
	    set rc 1
	} else {
	    pass "$test - $subtest (file change)"
	    set rc 0
	}
    }

    if {$systemtap_stapusr_user_exists} {
	set user "stapusr"
    } else {
	set user "stapsys"
    }

    # Now that we've changed the signature, try to run the module (which
    # should fail). Note that we only need to run the module once with
    # either stapusr or stapsys.
    if {$rc == 0} {
	set subtest "loading module with change signature"
	set cmd "staprun $unprivileged_module_path"
	lassign [server_ns_as_user $user $cmd] rc output
	# This *should* fail, since we munged the signature.
	if {$rc == 0} {
	    fail "$test - $subtest"
	} else {
	    pass "$test - $subtest"
	}
    }

    # Now lets change the module and see if we can load it. However,
    # changing the module is tricky. If for some reason the module
    # verifcation succeeds, if we've changed some random bits in the
    # module, we could cause the kernel to crash. So, instead, we'll
    # use the signature file for the 'stapusr' module with the
    # unprivileged module.
    set stapusr_module_sig_path "${stapusr_module_path}.sgn"
    set subtest "module rename"
    verbose -log "renaming $stapusr_module_sig_path $unprivileged_module_sig_path"
    if {! [catch {file rename -force $stapusr_module_sig_path \
		    $unprivileged_module_sig_path}]} {
	pass "$test - $subtest"

	set subtest "loading module with mismatched signature"
	set cmd "staprun $unprivileged_module_path"
	lassign [server_ns_as_user $user $cmd] rc output
	# This *should* fail, since the module and signature don't match.
	if {$rc == 0} {
	    fail "$test - $subtest"
	} else {
	    pass "$test - $subtest"
	}
    } else {
	fail "$test - $subtest"
    }
} else {
    untested "$test - $subtest"
}

shutdown_server