-
Notifications
You must be signed in to change notification settings - Fork 18
494 lines (472 loc) · 24.9 KB
/
ci.yml
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
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
---
# SDL task names take the form "<task_id> ([NE]/(NA|C|I|IP)) - <task_description>" where:
# - N: No evidence required
# - E: Evidence required
# - NA: Not Applicable
# - C: Complete
# - I: Incomplete
# - IP: In Progress
#
# List of SDL tasks that are NOT checked by this pipeline:
# - CT636: Trade compliance classification: Published free of nonstandard crypto
# - CT52: Obtain Open Source PBT Approval
# - CT38: Conduct security progress reviews
# - CT36: Register SW components in OneBOM
# - CT25: Perform gap analysis on SDL plan
# - CT23: Disposition security vulnerabilities
# - CT22: Conduct manual code reviews
# - CT47: Complete a risk assessment for reused components
name: CI
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
env:
CARGO_TERM_COLOR: always
SIMICS_PUBLIC_ISPM_VERSION: 1.7.5
# Simics base
SIMICS_PUBLIC_PACKAGE_VERSION_1000: 6.0.169
# QSP X86
SIMICS_PUBLIC_PACKAGE_VERSION_2096: 6.0.70
# QSP CPU
SIMICS_PUBLIC_PACKAGE_VERSION_8112: 6.0.17
jobs:
build_and_test:
name: Build and Test
strategy:
matrix:
simics_version: [
# Public package tests only check latest SIMICS release
"6.0.169",
]
container: ubuntu:22.04
runs-on: ubuntu-latest
steps:
- name: Install Dependencies
shell: bash
run: |
apt-get -y update && \
apt-get -y install \
git \
curl \
build-essential \
cmake \
git-lfs
- uses: actions/checkout@v3
with:
lfs: true
- uses: dtolnay/rust-toolchain@nightly
with:
toolchain: nightly
components: rustfmt,clippy,miri
- name: Install SIMICS (External)
shell: bash
run: |
mkdir -p "${HOME}/simics/ispm"
tar --strip-components=1 -C "${HOME}/simics/ispm" \
-xvf .github/simics/intel-simics-package-manager-${{ env.SIMICS_PUBLIC_ISPM_VERSION }}-linux64.tar.gz
"${HOME}/simics/ispm/ispm" \
packages \
--non-interactive \
--verbose \
--install-dir "${HOME}/simics" \
--install .github/simics/simics-pkg-1000-${{ env.SIMICS_PUBLIC_PACKAGE_VERSION_1000 }}-linux64.ispm \
--install .github/simics/simics-pkg-2096-${{ env.SIMICS_PUBLIC_PACKAGE_VERSION_2096 }}-linux64.ispm \
--install .github/simics/simics-pkg-8112-${{ env.SIMICS_PUBLIC_PACKAGE_VERSION_8112 }}-linux64.ispm
- name: Set up .env
shell: bash
run: |
echo "SIMICS_HOME=${HOME}/simics" > .env
- name: Build Project
run: |
cargo build --features=${{ matrix.simics_version }}
- name: Check Project
run: |
cargo clippy --features=${{ matrix.simics_version}}
- name: Test Project
run: |
cargo test --features=${{ matrix.simics_version }} || ( echo "❗ Tests failed for SIMICS version ${{ matrix.simics_version }}" && exit 1 )
echo "✅ Tests passed for SIMICS version ${{ matrix.simics_version }}"
- name: (T157, T375, T300) (N/C) - Temporary files must be cleaned up after the resource is used, Release resources when no longer needed, Test that temporary files are cleaned up after the resource is used
run: |
cargo test --manifest-path util/tmp-dir/Cargo.toml \
|| ( echo "❗ [T157] tmp-dir tests failed" && exit 1 )
echo "✅ [T157] tmp-dir tests pass"
echo "✅ [T375] Temporary file/directory resources are released, see T157 test results"
echo "✅ [T375] LibAFL Shared memory resources are released via clean shutdown in with ::send_exiting"
echo "✅ [T300] Temporary files are cleaned up. See T157."
- name: (T297, T162, T572, T595) (N/C) - Verify that target pathname is validated before retrieving local resources, Validate pathname before retrieving local resources, Check for symlinks before opening files, Test that your application checks for symlinks before opening files
run: |
cargo test --features=${{ matrix.simics_version }} --manifest-path simics-tests/Cargo.toml path \
|| ( echo "❗ [T297] Simics path tests failed" && exit 1 )
echo "✅ [T297] Simics path tests passed (tests check pathname validation)"
echo "✅ [T162] Simics path tests passed (tests check pathname validation)"
echo "✅ [T572] File paths are canonicalized/normalized before opening. See T297."
echo "✅ [T595] Symlinks are checked before using files. See T297."
- name: Build Docs
run: |
cargo doc --features=${{ matrix.simics_version }} --workspace \
--no-deps
- name: Test Docs
run: |
cargo test --doc --features=${{ matrix.simics_version }} --workspace \
--no-deps
static_analysis:
name: Run Static Analysis
container: ubuntu:22.04
runs-on: ubuntu-latest
steps:
- name: Install Dependencies
shell: bash
run: |
apt-get -y update && \
apt-get -y install \
git \
curl \
build-essential \
cmake \
git-lfs
- uses: actions/checkout@v3
with:
lfs: true
- uses: dtolnay/rust-toolchain@nightly
with:
toolchain: nightly
components: rustfmt,clippy,miri
- name: Install SIMICS (External)
shell: bash
run: |
mkdir -p "${HOME}/simics/ispm"
tar --strip-components=1 -C "${HOME}/simics/ispm" \
-xvf .github/simics/intel-simics-package-manager-${{ env.SIMICS_PUBLIC_ISPM_VERSION }}-linux64.tar.gz
"${HOME}/simics/ispm/ispm" \
packages \
--non-interactive \
--verbose \
--install-dir "${HOME}/simics" \
--install .github/simics/simics-pkg-1000-${{ env.SIMICS_PUBLIC_PACKAGE_VERSION_1000 }}-linux64.ispm \
--install .github/simics/simics-pkg-2096-${{ env.SIMICS_PUBLIC_PACKAGE_VERSION_2096 }}-linux64.ispm \
--install .github/simics/simics-pkg-8112-${{ env.SIMICS_PUBLIC_PACKAGE_VERSION_8112 }}-linux64.ispm
- name: Set up .env
shell: bash
run: |
echo "SIMICS_HOME=${HOME}/simics" > .env
- name: CT39 - Clippy Check Project
run: |
cargo clippy --features=${{ env.SIMICS_PUBLIC_PACKAGE_VERSION_1000 }} \
|| ( echo "❗ [CT39 (1/2)] Failed clippy static analysis checks" && exit 1 )
echo "✅ [CT39 (1/2)] Passed clippy static analysis checks"
- name: CT39 - MIRI Check Project
run: |
cargo clippy --features=${{ env.SIMICS_PUBLIC_PACKAGE_VERSION_1000 }}
MIRIFLAGS="-Zmiri-backtrace=full -Zmiri-disable-isolation -Zmiri-panic-on-unsupported" cargo \
miri test --features=${{ env.SIMICS_PUBLIC_PACKAGE_VERSION_1000 }} \
|| ( echo "❗ [CT39 (2/2)] Failed MIRI static analysis checks" && exit 1 )
echo "✅ [CT39 (2/2)] Passed MIRI static analysis checks"
fuzz_tests:
name: Run Fuzz Tests
container: ubuntu:22.04
runs-on: ubuntu-latest
steps:
- name: Install Dependencies
shell: bash
run: |
apt-get -y update && \
apt-get -y install \
git \
curl \
build-essential \
cmake \
git-lfs
- uses: actions/checkout@v3
with:
lfs: true
- uses: dtolnay/rust-toolchain@nightly
with:
toolchain: nightly
components: rustfmt,clippy,miri
- name: Install SIMICS (External)
shell: bash
run: |
mkdir -p "${HOME}/simics/ispm"
tar --strip-components=1 -C "${HOME}/simics/ispm" \
-xvf .github/simics/intel-simics-package-manager-${{ env.SIMICS_PUBLIC_ISPM_VERSION }}-linux64.tar.gz
"${HOME}/simics/ispm/ispm" \
packages \
--non-interactive \
--verbose \
--install-dir "${HOME}/simics" \
--install .github/simics/simics-pkg-1000-${{ env.SIMICS_PUBLIC_PACKAGE_VERSION_1000 }}-linux64.ispm \
--install .github/simics/simics-pkg-2096-${{ env.SIMICS_PUBLIC_PACKAGE_VERSION_2096 }}-linux64.ispm \
--install .github/simics/simics-pkg-8112-${{ env.SIMICS_PUBLIC_PACKAGE_VERSION_8112 }}-linux64.ispm
- name: Set up .env
shell: bash
run: |
echo "SIMICS_HOME=${HOME}/simics" > .env
- name: Install Cargo-Fuzz
run: |
cargo install cargo-fuzz
- name: CT632 (E/C) - Perform fuzz testing
run: |
cd util/version-tools
cargo fuzz build
timeout --preserve-status 600 cargo fuzz run \
fuzz_version_constraint_parse || exit 0
echo "Done fuzzing!"
if [ -d ./fuzz/artifacts ]; then
if find ./fuzz/artifacts -mindepth 1 -maxdepth 1 2> /dev/null | read -r; then
echo "❗ [CT632] Fuzz test found an issue"
exit 1
fi
fi
cd ../..
cd util/raw-cstr
cargo fuzz build
timeout --preserve-status 600 cargo fuzz run \
fuzz_raw_cstr || exit 0
echo "Done fuzzing!"
if [ -d ./fuzz/artifacts ]; then
if find ./fuzz/artifacts -mindepth 1 -maxdepth 1 2> /dev/null | read -r; then
echo "❗ [CT632] Fuzz test found an issue"
exit 1
fi
fi
cd ../..
echo "✅ [CT632] Fuzz test completed"
exit 0
super_lint:
name: Run Super Linter
container: github/super-linter
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
lfs: false
- name: (CT222) (E/C) - Use hadolint to evaluate Dockerfile configuration
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Rust validation is handled by build_and_test
VALIDATE_RUST_2015: false
VALIDATE_RUST_2018: false
VALIDATE_RUST_2021: false
VALIDATE_RUST_CLIPPY: false
# We have no non-example CPP in the codebase
VALIDATE_CPP: false
VALIDATE_CLANG_FORMAT: false
VALIDATE_JSCPD: false
# This is way too pedantic
VALIDATE_NATURAL_LANGUAGE: false
run: |
/action/lib/linter.sh || ( echo "❗ [CT222] Super linter found an issue (possibly Hadolint)" && exit 1 )
echo "✅ [CT222] Hadolint Dockerfile check passed"
scan_hello_world:
name: Scan Hello World EFI Builder Container
container: novafacing/kaniko-trivy-alpine:kaniko-v1.12.1-debug-trivy-v0.44.1-0.0.2
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
lfs: false
- name: Build Hello World Image
run: |
/kaniko/executor \
--build-arg "http_proxy=${http_proxy}" \
--build-arg "HTTP_PROXY=${HTTP_PROXY}" \
--build-arg "https_proxy=${https_proxy}" \
--build-arg "HTTPS_PROXY=${HTTPS_PROXY}" \
--build-arg "no_proxy=${no_proxy}" \
--build-arg "NO_PROXY=${NO_PROXY}" \
--build-arg "proxy=${HTTP_PROXY}" \
--snapshot-mode=redo \
--use-new-run \
--context examples/hello-world \
--dockerfile Dockerfile \
--no-push \
--tar-path /hello-world.tar \
--destination=image
- name: (T1187, T1186) (N/C) - Test if secrets are stored in Dockerfiles (Hello World Image)
run: |
/kaniko/trivy image --input /hello-world.tar
scan_x509_parse:
name: Scan X509Parse EFI Builder Container
container: novafacing/kaniko-trivy-alpine:kaniko-v1.12.1-debug-trivy-v0.44.1-0.0.2
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
lfs: false
- name: Build X509Parse Image
run: |
/kaniko/executor \
--build-arg "http_proxy=${http_proxy}" \
--build-arg "HTTP_PROXY=${HTTP_PROXY}" \
--build-arg "https_proxy=${https_proxy}" \
--build-arg "HTTPS_PROXY=${HTTPS_PROXY}" \
--build-arg "no_proxy=${no_proxy}" \
--build-arg "NO_PROXY=${NO_PROXY}" \
--build-arg "proxy=${HTTP_PROXY}" \
--snapshot-mode=redo \
--use-new-run \
--context examples/x509-parse \
--dockerfile Dockerfile \
--no-push \
--tar-path /x509-parse.tar \
--destination=image
- name: (T1187, T1186) (N/C) - Test if secrets are stored in Dockerfiles (X509Parse Image)
run: |
/kaniko/trivy image --input /x509-parse.tar
additional_sdl_checks:
name: Perform Additional SDL Checks
container: ubuntu:22.04
runs-on: ubuntu-latest
steps:
- name: Install Dependencies
run: |
apt-get -y update && \
apt-get -y install \
git \
curl \
jq \
wget \
build-essential \
cmake \
openssl \
libssl-dev \
pkg-config \
git-lfs
- uses: actions/checkout@v3
with:
lfs: false
- uses: dtolnay/rust-toolchain@nightly
with:
toolchain: nightly
components: rustfmt,clippy,miri
- name: Install Cargo Plugins
run: |
cargo install cargo-audit cargo-outdated
- name: CT256 (N/C) - Include security.md file in open source repos
run: |
[ -f SECURITY.md ] \
|| ( echo "❗ [CT256] Missing SECURITY.md file" && exit 1 )
echo "✅ [CT256] SECURITY.md file found"
- name: CT37 (N/NA) - Scan release package for malware
run: |
# We mark this task as NA because we do not publish any release
# package, so we check that we indeed cannot publish anything
grep -q "publish = false" 'Cargo.toml' || ( echo "❗ [CT37] Crate {} is publishable" && exit 1 )
find . -mindepth 2 -type f -name 'Cargo.toml' -not -path './target/*' -print0 2> /dev/null \
| xargs -0 -i bash -c \
'grep -qE "publish.workspace = true|publish = false" {} || ( echo "❗ [CT37] Crate {} is publishable" && exit 1 )' \
|| exit 1
echo "✅ [CT37] No release package is provided by this repository"
- name: (T152, T14, T174) (N/C) - Avoid asking for and using excessive permissions, Enforce Principle of least privilege, Test that the client application is not asking for excessive permissions
run: |
# All the crates I can find that escalate do so by setting uid at some
# point
find . -type f -name '*.rs' -print0 2> /dev/null \
| xargs -0 -i bash -c \
'! grep -Eq "sudo|setuid\(0\)" {} || ( echo "❗ [T152] sudo or setuid(0) found in {}" && exit 1 )' \
|| exit 1
echo "✅ [T152] Elevated permissions not requested or used"
- name: (T349, T350) (N/C) - Protect audit information and logs against unauthorized access, Verify that audit information is sufficiently protected
run: |
# shellcheck disable=SC2016
find . -type f -name '*.rs' -not -path './simics-api-sys/scripts/*' -print0 2> /dev/null \
| xargs -0 -i bash -c \
'MATCH=$(grep -A16 -E "File::|OpenOptions::" {} | grep -B16 -A16 -i "log"); if [ -n "${MATCH}" ]; then echo "${MATCH}" > /tmp/logmatch.$(printf {} | sed "s/\//-/g"); fi'
find /tmp -name 'logmatch.*' -print0 2> /dev/null \
| xargs -0 -i bash -c 'grep -qE "set_permissions.*0o[0-9]*700" {} || ( echo "❗ [T349] No set_permissions call with safe default permissions found after File:: or OpenOptions::" && exit 1 )'
echo "✅ [T349] Safe set_permissions call found for all File:: and OpenOptions:: with log mentioned"
echo "✅ [T350] Logs are protected. See T349."
- name: (T437, T438) (N/C) - Include log reduction and report generation capabilities, Verify that log reduction and report generation capabilities exist
run: |
RESULTS=$(find . -type f -name '*.rs' -not -path './target/*' -print0 2> /dev/null \
| xargs -0 -i bash -c \
'grep "with_filter" {}' | wc -l)
if [ "${RESULTS}" -eq 0 ]; then ( echo "❗ [T437] no 'with_filter' calls found to restrict tracing output" && exit 1 ); fi
echo "✅ [T437] 'with_filter' calls found to restrict tracing output"
echo "✅ [T438] Log reduction implemented with log levels. See T437."
- name: T633 (N/C) - Mitigate deadlock and recursion in services
run: |
echo "✅ [T633] Restarting event mgr and Rust threading guarantees used to mitigate deadlock/recursion "
- name: (T34, T31, T127, T519) (N/C) - Refuse overly-long, malformed, non-printable characters, Validate all forms of input, Test for null byte injection, Test that input validation is done on all forms of input
run: |
cat simics-fuzz/src/args/mod.rs
echo "✅ [T34] Strongly-typed argument parsing in use, strings UTF-8 enforced by Rust std"
echo "✅ [T31] Input arguments are validated. See T34 output."
echo "✅ [T127] Malformed inputs are rejected via strong argument typing. See T34."
echo "✅ [T519] Input validation implemented. See T34."
- name: (T45, T315) (N/C) - Log potential critical security events, Verify that potential security-critical events are logged
run: |
grep -A48 "let mut harness" simics-fuzz/src/fuzzer/mod.rs
echo "✅ [T45] This project is a security tool. Potential identified security issues logged by fuzzer loop"
echo "✅ [T315] Security critical events are logged. See T45."
- name: (T159, CT185, T403, T187) (N/C) - Follow best practices for secure error and exception handling, Implement full error and exception handling, Verify that errors and exceptions are securely handled, Verify that errors and exceptions are securely handled
run: |
find . -type f -name 'lib.rs' -not -path './target/*' -print0 2> /dev/null \
| xargs -0 -i bash -c \
'grep -q "unwrap_used" {} || ( echo "❗ [T159] No #![deny(clippy::unwrap_used)] directive found in {}" && exit 1 )'
echo "✅ [T159] #![deny(clippy::unwrap_used)] found in all lib.rs files"
echo "✅ [CT185] Full error and exception handling implemented. See T159 output."
echo "✅ [T403] Full error and exception handling implemented. See T159 output."
echo "✅ [T187] Full error and exception handling implemented. See T159 output."
- name: T205 (N/C) - Avoid inter-process race conditions
run: |
# This can't be grepped for
echo "✅ [T205] Data races are guarded against by using safe Rust in inter-process/inter-thread code"
- name: T206 (N/C) - Avoid TOCTOU race conditions against external resources
run: |
# This is very hard to grep for
echo "✅ [T206] Accessed resources are taken when they are checked"
- name: (T47, T229) (N/NA) - Do not log confidential data, Test that logs do not contain confidential data
run: |
echo "✅ [T47] This project does not deal with confidential data/PII"
echo "✅ [T229] This project does not deal with confidential data/PII. See T47."
- name: CT188 (N/C) - Configure minimal permissions on temporary files and directories
run: |
grep -i "DEFAULT_PERMISSIONS" util/tmp-dir/src/lib.rs
echo "✅ [CT188] Default permissions are safely set for temporary directories"
- name: T232 (N/C) - Verify that end-user transaction logs capture sufficient information
run: |
LOG_MESSAGES=$(find . -type f -name '*.rs' -not -path './target/*' -exec grep -E "trace\!|debug\!|info\!|warn\!|error\!" {} \; 2> /dev/null | wc -l)
echo "✅ [T232] ${LOG_MESSAGES} found in project"
# NOTE: We ignore vulnerabilities in GH actions' node packages explicitly, they
# are not relevant for us because we also use action checks
- name: (CT247/CT200) (N/C) - Scan 3rd-Party Components for Vulnerabilities, Verify that project is not using vulnerable 3rd party components
run: |
# shellcheck disable=SC2086,SC2143
LATEST="$(find '.github/dependabot' -name '*.csv' -print0 \
| xargs -r -0 ls -1 -t \
| head -n 1)"
if ! find '.github/dependabot' -name '*.csv' -mtime -14 | grep -q '.'; then
echo "❗ [CT247/CT200] No dependabot report found from last 2 weeks. Run ./scripts/dependabot.sh."
exit 1
fi
if tail -n+2 "${LATEST}" | grep -qv ".github/actions/toolchain"; then
cat "${LATEST}"
echo "❗ [CT247/CT200] Vulnerabilities found outside of github actions. Please remediate them."
exit 1
fi
echo "✅ [CT247/CT200] No dependabot vulnerabilities found"
- name: (CT72/CT98) (N/C) - Secure Configuration Guidance
run: |
echo "✅ [CT72/CT98] Manual secure configuration check:"
echo " - No 3rd party software/services distributed/deployed"
echo " - Dependencies configuration:"
echo " - LibAFL configured to *not* bind publicly by default"
echo " - Rust software builds with ASLR by default"
echo " - Features not used other than SIMICS version"
echo " - Compatibility settings used for SIMICS version"
echo " - No legacy features"
- name: (T186) (N/C) - Use recommended settings and latest patches for third party libraries and software
run: |
cargo audit
if ! cargo outdated --exit-code 1; then
echo "❗ [T186] Out of date third party dependencies found"
exit 1
fi
echo "✅ [T186] No outdated or vulnerable third party dependencies found"