Skip to content

Commit 29ca362

Browse files
committed
Add examples for composed configurations
Compose s1.toml with s2.toml and get s.toml, similar to s.json . Add golden file to check the sandboxer --debug output. These are the examples I used in my talk at Linux Security Summit Europe 2025: https://lsseu2025.sched.com/event/25GET Signed-off-by: Mickaël Salaün <mic@digikod.net>
1 parent b77a27f commit 29ca362

File tree

7 files changed

+257
-0
lines changed

7 files changed

+257
-0
lines changed

.github/workflows/ci.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ jobs:
7474
- name: Check JSON scoped
7575
run: ./schema/check.sh examples/mini-scoped.json
7676

77+
- name: Check JSON compose
78+
run: ./schema/check.sh tests/composition/s.json
79+
7780
cache_cargo_index:
7881
runs-on: ubuntu-24.04
7982
steps:
@@ -220,6 +223,15 @@ jobs:
220223
- name: Run the sandboxer example with scope restrictions
221224
run: rustup run stable cargo run --example sandboxer -- --json examples/mini-scoped.json true
222225

226+
- name: Run the sandboxer example with composed configurations, and compare to golden file
227+
run: |
228+
diff -u "tests/composition/golden-debug.txt" \
229+
<(rustup run stable cargo run --quiet --example sandboxer -- --toml tests/composition/source/s1.toml --toml tests/composition/source/s2.toml --debug true 2>&1)
230+
diff -u "tests/composition/golden-debug.txt" \
231+
<(rustup run stable cargo run --quiet --example sandboxer -- --toml tests/composition/s.toml --debug true 2>&1)
232+
diff -u "tests/composition/golden-debug.txt" \
233+
<(rustup run stable cargo run --quiet --example sandboxer -- --json tests/composition/s.json --debug true 2>&1)
234+
223235
- name: Check format
224236
run: rustup run stable cargo fmt --all -- --check
225237

tests/composition/README.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Composition of configurations
2+
3+
## [TOML source #1](source/s1.toml)
4+
5+
```toml
6+
[[variable]]
7+
name = "rw"
8+
literal = ["/tmp", "/var/tmp"]
9+
10+
# Main system file hierarchies can be read and executed.
11+
[[path_beneath]]
12+
allowed_access = ["v5.read_execute"]
13+
parent = ["/bin", "/lib", "/usr", "/dev", "/proc", "/etc"]
14+
15+
# Only allow writing to temporary and home directories.
16+
[[path_beneath]]
17+
allowed_access = ["v5.read_write"]
18+
parent = ["${rw}"]
19+
```
20+
21+
## [TOML source #2](source/s2.toml)
22+
23+
```toml
24+
[[variable]]
25+
name = "rw"
26+
literal = ["/home/user/tmp"]
27+
28+
[[ruleset]]
29+
handled_access_fs = ["v4.all"]
30+
31+
# Custom apps.
32+
[[path_beneath]]
33+
allowed_access = ["v4.read_execute"]
34+
parent = ["/home/user/bin"]
35+
```
36+
37+
## [TOML composition](s.toml)
38+
39+
```toml
40+
[[variable]]
41+
name = "rw"
42+
literal = ["/tmp", "/var/tmp", "/home/user/tmp"]
43+
44+
# Main system file hierarchies can be read and executed.
45+
[[path_beneath]]
46+
allowed_access = ["v4.read_execute"]
47+
parent = ["/bin", "/lib", "/usr", "/dev", "/proc", "/etc", "/home/user/bin"]
48+
49+
# Only allow writing to temporary and home directories.
50+
[[path_beneath]]
51+
allowed_access = ["v4.read_write"]
52+
parent = ["${rw}"]
53+
```
54+
55+
## [JSON composition](s.json)
56+
57+
```json
58+
{
59+
"variable": [
60+
{
61+
"name": "rw",
62+
"literal": [
63+
"/tmp",
64+
"/var/tmp",
65+
"/home/user/tmp"
66+
]
67+
}
68+
],
69+
"pathBeneath": [
70+
{
71+
"allowedAccess": [
72+
"v4.read_execute"
73+
],
74+
"parent": [
75+
"/bin",
76+
"/lib",
77+
"/usr",
78+
"/dev",
79+
"/proc",
80+
"/etc",
81+
"/home/user/bin"
82+
]
83+
},
84+
{
85+
"allowedAccess": [
86+
"v4.read_write"
87+
],
88+
"parent": [
89+
"${rw}"
90+
]
91+
}
92+
]
93+
}
94+
```

tests/composition/golden-debug.txt

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
ResolvedConfig {
2+
handled_fs: BitFlags<AccessFs> {
3+
bits: 0b111111111111111,
4+
flags: Execute | WriteFile | ReadFile | ReadDir | RemoveDir | RemoveFile | MakeChar | MakeDir | MakeReg | MakeSock | MakeFifo | MakeBlock | MakeSym | Refer | Truncate,
5+
},
6+
handled_net: BitFlags<AccessNet> {
7+
bits: 0b0,
8+
},
9+
scoped: BitFlags<Scope> {
10+
bits: 0b0,
11+
},
12+
rules_path_beneath: {
13+
"/bin": BitFlags<AccessFs> {
14+
bits: 0b10000000001101,
15+
flags: Execute | ReadFile | ReadDir | Refer,
16+
},
17+
"/dev": BitFlags<AccessFs> {
18+
bits: 0b10000000001101,
19+
flags: Execute | ReadFile | ReadDir | Refer,
20+
},
21+
"/etc": BitFlags<AccessFs> {
22+
bits: 0b10000000001101,
23+
flags: Execute | ReadFile | ReadDir | Refer,
24+
},
25+
"/home/user/bin": BitFlags<AccessFs> {
26+
bits: 0b10000000001101,
27+
flags: Execute | ReadFile | ReadDir | Refer,
28+
},
29+
"/home/user/tmp": BitFlags<AccessFs> {
30+
bits: 0b111111111111110,
31+
flags: WriteFile | ReadFile | ReadDir | RemoveDir | RemoveFile | MakeChar | MakeDir | MakeReg | MakeSock | MakeFifo | MakeBlock | MakeSym | Refer | Truncate,
32+
},
33+
"/lib": BitFlags<AccessFs> {
34+
bits: 0b10000000001101,
35+
flags: Execute | ReadFile | ReadDir | Refer,
36+
},
37+
"/proc": BitFlags<AccessFs> {
38+
bits: 0b10000000001101,
39+
flags: Execute | ReadFile | ReadDir | Refer,
40+
},
41+
"/tmp": BitFlags<AccessFs> {
42+
bits: 0b111111111111110,
43+
flags: WriteFile | ReadFile | ReadDir | RemoveDir | RemoveFile | MakeChar | MakeDir | MakeReg | MakeSock | MakeFifo | MakeBlock | MakeSym | Refer | Truncate,
44+
},
45+
"/usr": BitFlags<AccessFs> {
46+
bits: 0b10000000001101,
47+
flags: Execute | ReadFile | ReadDir | Refer,
48+
},
49+
"/var/tmp": BitFlags<AccessFs> {
50+
bits: 0b111111111111110,
51+
flags: WriteFile | ReadFile | ReadDir | RemoveDir | RemoveFile | MakeChar | MakeDir | MakeReg | MakeSock | MakeFifo | MakeBlock | MakeSym | Refer | Truncate,
52+
},
53+
},
54+
rules_net_port: {},
55+
}
56+
Ignored rule errors: [
57+
PathFd(
58+
OpenCall {
59+
source: Os {
60+
code: 2,
61+
kind: NotFound,
62+
message: "No such file or directory",
63+
},
64+
path: "/home/user/bin",
65+
},
66+
),
67+
PathFd(
68+
OpenCall {
69+
source: Os {
70+
code: 2,
71+
kind: NotFound,
72+
message: "No such file or directory",
73+
},
74+
path: "/home/user/tmp",
75+
},
76+
),
77+
]
78+
Executing true in a sandbox...

tests/composition/s.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"variable": [
3+
{
4+
"name": "rw",
5+
"literal": [
6+
"/tmp",
7+
"/var/tmp",
8+
"/home/user/tmp"
9+
]
10+
}
11+
],
12+
"pathBeneath": [
13+
{
14+
"allowedAccess": [
15+
"v4.read_execute"
16+
],
17+
"parent": [
18+
"/bin",
19+
"/lib",
20+
"/usr",
21+
"/dev",
22+
"/proc",
23+
"/etc",
24+
"/home/user/bin"
25+
]
26+
},
27+
{
28+
"allowedAccess": [
29+
"v4.read_write"
30+
],
31+
"parent": [
32+
"${rw}"
33+
]
34+
}
35+
]
36+
}

tests/composition/s.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[[variable]]
2+
name = "rw"
3+
literal = ["/tmp", "/var/tmp", "/home/user/tmp"]
4+
5+
# Main system file hierarchies can be read and executed.
6+
[[path_beneath]]
7+
allowed_access = ["v4.read_execute"]
8+
parent = ["/bin", "/lib", "/usr", "/dev", "/proc", "/etc", "/home/user/bin"]
9+
10+
# Only allow writing to temporary and home directories.
11+
[[path_beneath]]
12+
allowed_access = ["v4.read_write"]
13+
parent = ["${rw}"]

tests/composition/source/s1.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[[variable]]
2+
name = "rw"
3+
literal = ["/tmp", "/var/tmp"]
4+
5+
# Main system file hierarchies can be read and executed.
6+
[[path_beneath]]
7+
allowed_access = ["v5.read_execute"]
8+
parent = ["/bin", "/lib", "/usr", "/dev", "/proc", "/etc"]
9+
10+
# Only allow writing to temporary and home directories.
11+
[[path_beneath]]
12+
allowed_access = ["v5.read_write"]
13+
parent = ["${rw}"]

tests/composition/source/s2.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[[variable]]
2+
name = "rw"
3+
literal = ["/home/user/tmp"]
4+
5+
[[ruleset]]
6+
handled_access_fs = ["v4.all"]
7+
8+
# Custom apps.
9+
[[path_beneath]]
10+
allowed_access = ["v4.read_execute"]
11+
parent = ["/home/user/bin"]

0 commit comments

Comments
 (0)