Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tests/sys/kern/jailmeta.sh
39478 views
1
#
2
# SPDX-License-Identifier: BSD-2-Clause
3
#
4
# Copyright (c) 2024 SkunkWerks GmbH
5
#
6
# This software was developed by Igor Ostapenko <[email protected]>
7
# under sponsorship from SkunkWerks GmbH.
8
#
9
10
setup()
11
{
12
# Check if we have enough buffer space for testing
13
if [ $(sysctl -n security.jail.meta_maxbufsize) -lt 128 ]; then
14
atf_skip "sysctl security.jail.meta_maxbufsize must be 128+ for testing."
15
fi
16
}
17
18
atf_test_case "jail_create" "cleanup"
19
jail_create_head()
20
{
21
atf_set descr 'Test that metadata can be set upon jail creation with jail(8)'
22
atf_set require.user root
23
atf_set execenv jail
24
}
25
jail_create_body()
26
{
27
setup
28
29
atf_check -s not-exit:0 -e match:"not found" -o ignore \
30
jls -jj
31
32
atf_check -s exit:0 \
33
jail -c name=j persist meta="a b c" env="C B A"
34
35
atf_check -s exit:0 -o inline:"a b c\n" \
36
jls -jj meta
37
atf_check -s exit:0 -o inline:"C B A\n" \
38
jls -jj env
39
}
40
jail_create_cleanup()
41
{
42
jail -r j
43
return 0
44
}
45
46
atf_test_case "jail_modify" "cleanup"
47
jail_modify_head()
48
{
49
atf_set descr 'Test that metadata can be modified after jail creation with jail(8)'
50
atf_set require.user root
51
atf_set execenv jail
52
}
53
jail_modify_body()
54
{
55
setup
56
57
atf_check -s not-exit:0 -e match:"not found" -o ignore \
58
jls -jj
59
60
atf_check -s exit:0 \
61
jail -c name=j persist meta="a b c" env="CAB"
62
63
atf_check -s exit:0 -o inline:"a b c\n" \
64
jls -jj meta
65
atf_check -s exit:0 -o inline:"CAB\n" \
66
jls -jj env
67
68
atf_check -s exit:0 \
69
jail -m name=j meta="t1=A t2=B" env="CAB2"
70
71
atf_check -s exit:0 -o inline:"t1=A t2=B\n" \
72
jls -jj meta
73
atf_check -s exit:0 -o inline:"CAB2\n" \
74
jls -jj env
75
}
76
jail_modify_cleanup()
77
{
78
jail -r j
79
return 0
80
}
81
82
atf_test_case "jail_add" "cleanup"
83
jail_add_head()
84
{
85
atf_set descr 'Test that metadata can be added to an existing jail with jail(8)'
86
atf_set require.user root
87
atf_set execenv jail
88
}
89
jail_add_body()
90
{
91
setup
92
93
atf_check -s not-exit:0 -e match:"not found" -o ignore \
94
jls -jj
95
96
atf_check -s exit:0 \
97
jail -c name=j persist host.hostname=jail1
98
99
atf_check -s exit:0 -o inline:'""\n' \
100
jls -jj meta
101
atf_check -s exit:0 -o inline:'""\n' \
102
jls -jj env
103
104
atf_check -s exit:0 \
105
jail -m name=j meta="$(jot 3 1 3)" env="$(jot 2 11 12)"
106
107
atf_check -s exit:0 -o inline:"1\n2\n3\n" \
108
jls -jj meta
109
atf_check -s exit:0 -o inline:"11\n12\n" \
110
jls -jj env
111
}
112
jail_add_cleanup()
113
{
114
jail -r j
115
return 0
116
}
117
118
atf_test_case "jail_reset" "cleanup"
119
jail_reset_head()
120
{
121
atf_set descr 'Test that metadata can be reset to an empty string with jail(8)'
122
atf_set require.user root
123
atf_set execenv jail
124
}
125
jail_reset_body()
126
{
127
setup
128
129
atf_check -s not-exit:0 -e match:"not found" -o ignore \
130
jls -jj
131
132
atf_check -s exit:0 \
133
jail -c name=j persist meta="123" env="456"
134
135
atf_check -s exit:0 -o inline:"123\n" \
136
jls -jj meta
137
atf_check -s exit:0 -o inline:"456\n" \
138
jls -jj env
139
140
atf_check -s exit:0 \
141
jail -m name=j meta= env=
142
143
atf_check -s exit:0 -o inline:'""\n' \
144
jls -jj meta
145
atf_check -s exit:0 -o inline:'""\n' \
146
jls -jj env
147
}
148
jail_reset_cleanup()
149
{
150
jail -r j
151
return 0
152
}
153
154
atf_test_case "jls_libxo_json" "cleanup"
155
jls_libxo_json_head()
156
{
157
atf_set descr 'Test that metadata can be read with jls(8) using libxo JSON'
158
atf_set require.user root
159
atf_set execenv jail
160
}
161
jls_libxo_json_body()
162
{
163
setup
164
165
atf_check -s not-exit:0 -e match:"not found" -o ignore \
166
jls -jj
167
168
atf_check -s exit:0 \
169
jail -c name=j persist meta="a b c" env="1 2 3"
170
171
atf_check -s exit:0 -o inline:'{"__version": "2", "jail-information": {"jail": [{"name":"j","meta":"a b c"}]}}\n' \
172
jls -jj --libxo json name meta
173
atf_check -s exit:0 -o inline:'{"__version": "2", "jail-information": {"jail": [{"env":"1 2 3"}]}}\n' \
174
jls -jj --libxo json env
175
}
176
jls_libxo_json_cleanup()
177
{
178
jail -r j
179
return 0
180
}
181
182
atf_test_case "flua_create" "cleanup"
183
flua_create_head()
184
{
185
atf_set descr 'Test that metadata can be set upon jail creation with flua'
186
atf_set require.user root
187
atf_set execenv jail
188
}
189
flua_create_body()
190
{
191
setup
192
193
atf_check -s not-exit:0 -e match:"not found" -o ignore \
194
jls -jj
195
196
atf_check -s exit:0 \
197
/usr/libexec/flua -ljail -e 'jail.setparams("j", {["meta"]="t1 t2=v2", ["env"]="BAC", ["persist"]="true"}, jail.CREATE)'
198
199
atf_check -s exit:0 -o inline:"t1 t2=v2\n" \
200
/usr/libexec/flua -ljail -e 'jid, res = jail.getparams("j", {"meta"}); print(res["meta"])'
201
atf_check -s exit:0 -o inline:"BAC\n" \
202
/usr/libexec/flua -ljail -e 'jid, res = jail.getparams("j", {"env"}); print(res["env"])'
203
}
204
flua_create_cleanup()
205
{
206
jail -r j
207
return 0
208
}
209
210
atf_test_case "flua_modify" "cleanup"
211
flua_modify_head()
212
{
213
atf_set descr 'Test that metadata can be changed with flua after jail creation'
214
atf_set require.user root
215
atf_set execenv jail
216
}
217
flua_modify_body()
218
{
219
setup
220
221
atf_check -s not-exit:0 -e match:"not found" -o ignore \
222
jls -jj
223
224
atf_check -s exit:0 \
225
jail -c name=j persist meta="ABC" env="123"
226
227
atf_check -s exit:0 -o inline:"ABC\n" \
228
jls -jj meta
229
atf_check -s exit:0 -o inline:"123\n" \
230
jls -jj env
231
232
atf_check -s exit:0 \
233
/usr/libexec/flua -ljail -e 'jail.setparams("j", {["meta"]="t1 t2=v", ["env"]="4"}, jail.UPDATE)'
234
235
atf_check -s exit:0 -o inline:"t1 t2=v\n" \
236
jls -jj meta
237
atf_check -s exit:0 -o inline:"4\n" \
238
jls -jj env
239
}
240
flua_modify_cleanup()
241
{
242
jail -r j
243
return 0
244
}
245
246
atf_test_case "env_readable_by_jail" "cleanup"
247
env_readable_by_jail_head()
248
{
249
atf_set descr 'Test that a jail can read its own env parameter via sysctl(8)'
250
atf_set require.user root
251
atf_set execenv jail
252
}
253
env_readable_by_jail_body()
254
{
255
setup
256
257
atf_check -s not-exit:0 -e match:"not found" -o ignore \
258
jls -jj
259
260
atf_check -s exit:0 \
261
jail -c name=j persist meta="a b c" env="CBA"
262
263
atf_check -s exit:0 -o inline:"a b c\n" \
264
jls -jj meta
265
atf_check -s exit:0 -o inline:"CBA\n" \
266
jls -jj env
267
268
atf_check -s exit:0 -o inline:"CBA\n" \
269
jexec j sysctl -n security.jail.env
270
}
271
env_readable_by_jail_cleanup()
272
{
273
jail -r j
274
return 0
275
}
276
277
atf_test_case "not_inheritable" "cleanup"
278
not_inheritable_head()
279
{
280
atf_set descr 'Test that a jail does not inherit metadata from its parent jail'
281
atf_set require.user root
282
atf_set execenv jail
283
}
284
not_inheritable_body()
285
{
286
setup
287
288
atf_check -s not-exit:0 -e match:"not found" -o ignore \
289
jls -j parent
290
291
atf_check -s exit:0 \
292
jail -c name=parent children.max=1 persist meta="abc" env="cba"
293
294
jexec parent jail -c name=child persist
295
296
atf_check -s exit:0 -o inline:"abc\n" \
297
jls -j parent meta
298
atf_check -s exit:0 -o inline:'""\n' \
299
jls -j parent.child meta
300
301
atf_check -s exit:0 -o inline:"cba\n" \
302
jexec parent sysctl -n security.jail.env
303
atf_check -s exit:0 -o inline:"\n" \
304
jexec parent.child sysctl -n security.jail.env
305
}
306
not_inheritable_cleanup()
307
{
308
jail -r parent.child
309
jail -r parent
310
return 0
311
}
312
313
atf_test_case "maxbufsize" "cleanup"
314
maxbufsize_head()
315
{
316
atf_set descr 'Test that metadata buffer maximum size can be changed'
317
atf_set require.user root
318
atf_set is.exclusive true
319
}
320
maxbufsize_body()
321
{
322
setup
323
324
jn=jailmeta_maxbufsize
325
326
atf_check -s not-exit:0 -e match:"not found" -o ignore \
327
jls -j $jn
328
329
# the size counts string length and the trailing \0 char
330
origmax=$(sysctl -n security.jail.meta_maxbufsize)
331
332
# must be fine with current max
333
atf_check -s exit:0 \
334
jail -c name=$jn persist meta="$(printf %$((origmax-1))s)"
335
atf_check -s exit:0 -o inline:"${origmax}\n" \
336
jls -j $jn meta | wc -c
337
#
338
atf_check -s exit:0 \
339
jail -m name=$jn env="$(printf %$((origmax-1))s)"
340
atf_check -s exit:0 -o inline:"${origmax}\n" \
341
jls -j $jn env | wc -c
342
343
# should not allow exceeding current max
344
atf_check -s not-exit:0 -e match:"too large" \
345
jail -m name=$jn meta="$(printf %${origmax}s)"
346
#
347
atf_check -s not-exit:0 -e match:"too large" \
348
jail -m name=$jn env="$(printf %${origmax}s)"
349
350
# should allow the same size with increased max
351
newmax=$((origmax + 1))
352
sysctl security.jail.meta_maxbufsize=$newmax
353
atf_check -s exit:0 \
354
jail -m name=$jn meta="$(printf %${origmax}s)"
355
atf_check -s exit:0 -o inline:"${origmax}\n" \
356
jls -j $jn meta | wc -c
357
#
358
atf_check -s exit:0 \
359
jail -m name=$jn env="$(printf %${origmax}s)"
360
atf_check -s exit:0 -o inline:"${origmax}\n" \
361
jls -j $jn env | wc -c
362
363
# decrease back to the original max
364
sysctl security.jail.meta_maxbufsize=$origmax
365
atf_check -s not-exit:0 -e match:"too large" \
366
jail -m name=$jn meta="$(printf %${origmax}s)"
367
#
368
atf_check -s not-exit:0 -e match:"too large" \
369
jail -m name=$jn env="$(printf %${origmax}s)"
370
371
# the previously set long meta is still readable as is
372
# due to the soft limit remains higher than the hard limit
373
atf_check_equal '${newmax}' '$(sysctl -n security.jail.param.meta)'
374
atf_check_equal '${newmax}' '$(sysctl -n security.jail.param.env)'
375
atf_check -s exit:0 -o inline:"${origmax}\n" \
376
jls -j $jn meta | wc -c
377
#
378
atf_check -s exit:0 -o inline:"${origmax}\n" \
379
jls -j $jn env | wc -c
380
}
381
maxbufsize_cleanup()
382
{
383
jail -r jailmeta_maxbufsize
384
return 0
385
}
386
387
atf_test_case "keyvalue" "cleanup"
388
keyvalue_head()
389
{
390
atf_set descr 'Test that metadata can be handled as a set of key=value\n strings using jail(8), jls(8), and flua'
391
atf_set require.user root
392
atf_set execenv jail
393
}
394
keyvalue_generic()
395
{
396
local meta=$1
397
398
atf_check -sexit:0 -oinline:'""\n' jls -jj $meta
399
400
# Note: each sub-case depends on the results of the previous ones
401
402
# Should be able to extract a key added manually
403
atf_check -sexit:0 jail -m name=j $meta="a=1"
404
atf_check -sexit:0 -oinline:'a=1\n' jls -jj $meta
405
atf_check -sexit:0 -oinline:'1\n' jls -jj $meta.a
406
atf_check -sexit:0 jail -m name=j $meta="$(printf 'a=2\nb=3')"
407
atf_check -sexit:0 -oinline:'a=2\nb=3\n' jls -jj $meta
408
atf_check -sexit:0 -oinline:'2\n' jls -jj $meta.a
409
atf_check -sexit:0 -oinline:'3\n' jls -jj $meta.b
410
411
# Should provide nothing for a non-found key
412
atf_check -sexit:0 -oinline:'\n' jls -jj $meta.c
413
414
# Should be able to lookup multiple keys at once
415
atf_check -sexit:0 -oinline:'3 2\n' jls -jj $meta.b $meta.a
416
417
# Should be able to lookup keys and the whole buffer at once
418
atf_check -sexit:0 -oinline:'3 a=2\nb=3 2\n' jls -jj $meta.b $meta $meta.a
419
420
# Should be able to lookup a key using libxo-based JSON output
421
s='{"__version": "2", "jail-information": {"jail": [{"'$meta'.b":"3"}]}}\n'
422
atf_check -s exit:0 -o inline:"$s" jls -jj --libxo json $meta.b
423
424
# Should provide nothing for a non-found key using libxo-based JSON output
425
s='{"__version": "2", "jail-information": {"jail": [{}]}}\n'
426
atf_check -s exit:0 -o inline:"$s" jls -jj --libxo json $meta.c $meta.d
427
428
# Should be able to lookup a key using flua
429
atf_check -s exit:0 -o inline:"2\n" \
430
/usr/libexec/flua -ljail -e 'jid, res = jail.getparams("j", {"'$meta'.a"}); print(res["'$meta'.a"])'
431
432
# Should provide nil for a non-found key using flua
433
atf_check -s exit:0 -o inline:"true\n" \
434
/usr/libexec/flua -ljail -e 'jid, res = jail.getparams("j", {"'$meta'.meta"}); print(res["'$meta'.meta"] == nil)'
435
436
# Should allow resetting a buffer
437
atf_check -sexit:0 jail -m name=j $meta=
438
atf_check -sexit:0 -oinline:' "" \n' jls -jj $meta.c $meta $meta.a
439
440
# Should allow adding a new key
441
atf_check -sexit:0 jail -m name=j $meta.a=1
442
atf_check -sexit:0 -oinline:'1\n' jls -jj $meta.a
443
atf_check -sexit:0 -oinline:'a=1\n' jls -jj $meta
444
445
# Should allow adding multiple new keys at once
446
atf_check -sexit:0 jail -m name=j $meta.c=3 $meta.b=2
447
atf_check -sexit:0 -oinline:'3\n' jls -jj $meta.c
448
atf_check -sexit:0 -oinline:'2\n' jls -jj $meta.b
449
atf_check -sexit:0 -oinline:'b=2\nc=3\na=1\n' jls -jj $meta
450
451
# Should replace existing keys
452
atf_check -sexit:0 jail -m name=j $meta.a=A $meta.c=C
453
atf_check -sexit:0 -oinline:'A\n' jls -jj $meta.a
454
atf_check -sexit:0 -oinline:'C\n' jls -jj $meta.c
455
atf_check -sexit:0 -oinline:'c=C\na=A\nb=2\n' jls -jj $meta
456
457
# Should treat empty value correctly
458
atf_check -sexit:0 jail -m name=j $meta.a=
459
atf_check -sexit:0 -oinline:'""\n' jls -jj $meta.a
460
atf_check -sexit:0 -oinline:'a=\nc=C\nb=2\n' jls -jj $meta
461
462
# Should treat NULL value as a key removal
463
atf_check -sexit:0 -oinline:'2\n' jls -jj $meta.b
464
atf_check -sexit:0 jail -m name=j $meta.b
465
atf_check -sexit:0 -oinline:'\n' jls -jj $meta.b
466
atf_check -sexit:0 -oinline:'a=\nc=C\n' jls -jj $meta
467
468
# Should allow changing the whole buffer and per key at once (order matters)
469
atf_check -sexit:0 jail -m name=j $meta.a=1 $meta=ttt $meta.b=2
470
atf_check -sexit:0 -oinline:'\n' jls -jj $meta.a
471
atf_check -sexit:0 -oinline:'2\n' jls -jj $meta.b
472
atf_check -sexit:0 -oinline:'b=2\nttt\n' jls -jj $meta
473
474
# Should treat only the first equal sign as syntax
475
atf_check -sexit:0 jail -m name=j $meta.b==
476
atf_check -sexit:0 -oinline:'=\n' jls -jj $meta.b
477
atf_check -sexit:0 -oinline:'b==\nttt\n' jls -jj $meta
478
479
# Should allow adding or modifying keys using flua
480
atf_check -s exit:0 \
481
/usr/libexec/flua -ljail -e 'jail.setparams("j", {["'$meta.b'"]="ttt", ["'$meta'.c"]="C"}, jail.UPDATE)'
482
atf_check -sexit:0 -oinline:'ttt\n' jls -jj $meta.b
483
atf_check -sexit:0 -oinline:'C\n' jls -jj $meta.c
484
485
# Should allow key removal using flua
486
atf_check -s exit:0 \
487
/usr/libexec/flua -ljail -e 'jail.setparams("j", {["'$meta.c'"] = {}}, jail.UPDATE)'
488
atf_check -sexit:0 -oinline:'\n' jls -jj $meta.c
489
atf_check -s exit:0 \
490
/usr/libexec/flua -ljail -e 'jail.setparams("j", {["'$meta.b'"] = false}, jail.UPDATE)'
491
atf_check -sexit:0 -oinline:'\n' jls -jj $meta.b
492
493
# Should respectively support "jls -s" for a missing key
494
atf_check -sexit:0 -oinline:''$meta'.missing\n' jls -jj -s $meta.missing
495
}
496
keyvalue_body()
497
{
498
setup
499
500
atf_check -s exit:0 \
501
jail -c name=j persist meta env
502
503
keyvalue_generic "meta"
504
keyvalue_generic "env"
505
}
506
keyvalue_cleanup()
507
{
508
jail -r j
509
return 0
510
}
511
512
atf_test_case "keyvalue_contention" "cleanup"
513
keyvalue_contention_head()
514
{
515
atf_set descr 'Try to stress metadata read/write mechanism with some contention'
516
atf_set require.user root
517
atf_set execenv jail
518
atf_set timeout 30
519
}
520
keyvalue_stresser()
521
{
522
local jailname=$1
523
local modifier=$2
524
525
while true
526
do
527
jail -m name=$jailname $modifier
528
done
529
}
530
keyvalue_contention_body()
531
{
532
setup
533
534
atf_check -s exit:0 jail -c name=j persist meta env
535
536
keyvalue_stresser "j" "meta.a=1" &
537
apid=$!
538
keyvalue_stresser "j" "meta.b=2" &
539
bpid=$!
540
keyvalue_stresser "j" "env.c=3" &
541
cpid=$!
542
keyvalue_stresser "j" "env.d=4" &
543
dpid=$!
544
545
for it in $(jot 8)
546
do
547
jail -m name=j meta='meta=META' env='env=ENV'
548
sleep 1
549
atf_check -sexit:0 -oinline:'1\n' jls -jj meta.a
550
atf_check -sexit:0 -oinline:'2\n' jls -jj meta.b
551
atf_check -sexit:0 -oinline:'3\n' jls -jj env.c
552
atf_check -sexit:0 -oinline:'4\n' jls -jj env.d
553
atf_check -sexit:0 -oinline:'META\n' jls -jj meta.meta
554
atf_check -sexit:0 -oinline:'ENV\n' jls -jj env.env
555
done
556
557
# TODO: Think of adding a stresser on the kernel side which does
558
# osd_set() w/o allprison lock. It could test the compare
559
# and swap mechanism in jm_osd_method_set().
560
561
kill -9 $apid $bpid $cpid $dpid
562
}
563
keyvalue_contention_cleanup()
564
{
565
jail -r j
566
return 0
567
}
568
569
atf_init_test_cases()
570
{
571
atf_add_test_case "jail_create"
572
atf_add_test_case "jail_modify"
573
atf_add_test_case "jail_add"
574
atf_add_test_case "jail_reset"
575
576
atf_add_test_case "jls_libxo_json"
577
578
atf_add_test_case "flua_create"
579
atf_add_test_case "flua_modify"
580
581
atf_add_test_case "env_readable_by_jail"
582
atf_add_test_case "not_inheritable"
583
584
atf_add_test_case "maxbufsize"
585
586
atf_add_test_case "keyvalue"
587
atf_add_test_case "keyvalue_contention"
588
}
589
590