tvl-depot/tools/rust-crates-advisory/default.nix
sterni 6c4e447587 feat(rust-crates-advisories): check 3p crates together w/ lock files
Instead of the strict check-all-our-crates, generate a fake Cargo.lock
and add it to the report generated by check-all-our-lock-files.
check-all-our-crates was a reimplementation of cargo-audit anyways and
prevented us from updating the advisory db due to its strict
model (failing on any advisory).

Change-Id: I264a7f1a5058a527cbc46d26225352ecd437a22b
Reviewed-on: https://cl.tvl.fyi/c/depot/+/5230
Tested-by: BuildkiteCI
Reviewed-by: tazjin <tazjin@tvl.su>
2022-02-13 18:42:44 +00:00

200 lines
4.7 KiB
Nix
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{ depot, pkgs, lib, ... }:
let
bins =
depot.nix.getBins pkgs.s6-portable-utils [ "s6-ln" "s6-cat" "s6-echo" "s6-mkdir" "s6-test" "s6-touch" "s6-dirname" ]
// depot.nix.getBins pkgs.coreutils [ "printf" ]
// depot.nix.getBins pkgs.lr [ "lr" ]
// depot.nix.getBins pkgs.cargo-audit [ "cargo-audit" ]
// depot.nix.getBins pkgs.jq [ "jq" ]
// depot.nix.getBins pkgs.findutils [ "find" ]
// depot.nix.getBins pkgs.gnused [ "sed" ]
;
crate-advisories = "${depot.third_party.rustsec-advisory-db}/crates";
our-crates = lib.filter (v: v ? outPath)
(builtins.attrValues depot.third_party.rust-crates);
our-crates-lock-file = pkgs.writeText "our-crates-Cargo.lock"
(lib.concatMapStrings
(crate: ''
[[package]]
name = "${crate.crateName}"
version = "${crate.version}"
source = "registry+https://github.com/rust-lang/crates.io-index"
'')
our-crates);
check-security-advisory = depot.nix.writers.rustSimple
{
name = "parse-security-advisory";
dependencies = [
depot.third_party.rust-crates.toml
depot.third_party.rust-crates.semver
];
}
(builtins.readFile ./check-security-advisory.rs);
# $1 is the directory with advisories for crate $2 with version $3
check-crate-advisory = depot.nix.writeExecline "check-crate-advisory" { readNArgs = 3; } [
"pipeline"
[ bins.lr "-0" "-t" "depth == 1" "$1" ]
"forstdin"
"-0"
"-Eo"
"0"
"advisory"
"if"
[ depot.tools.eprintf "advisory %s\n" "$advisory" ]
check-security-advisory
"$advisory"
"$3"
];
# Run through everything in the `crate-advisories` repository
# and check whether we can parse all the advisories without crashing.
test-parsing-all-security-advisories = depot.nix.runExecline "check-all-our-crates" { } [
"pipeline"
[ bins.lr "-0" "-t" "depth == 1" crate-advisories ]
"if"
[
# this will succeed as long as check-crate-advisory doesnt `panic!()` (status 101)
"forstdin"
"-0"
"-E"
"-x"
"101"
"crate_advisories"
check-crate-advisory
"$crate_advisories"
"foo"
"0.0.0"
]
"importas"
"out"
"out"
bins.s6-touch
"$out"
];
lock-file-report = pkgs.writers.writeBash "lock-file-report" ''
set -u
if test "$#" -lt 2; then
echo "Usage: $0 IDENTIFIER LOCKFILE [CHECKLIST [MAINTAINERS]]" >&2
echo 2>&1
echo " IDENTIFIER Unique string describing the lock file" >&2
echo " LOCKFILE Path to Cargo.lock file" >&2
echo " CHECKLIST Whether to use GHFM checklists in the output (true or false)" >&2
echo " MAINTAINERS List of @names to cc in case of advisories" >&2
exit 100
fi
"${bins.cargo-audit}" audit --json --no-fetch \
--db "${depot.third_party.rustsec-advisory-db}" \
--file "$2" \
| "${bins.jq}" --raw-output --join-output \
--from-file "${./format-audit-result.jq}" \
--arg maintainers "''${4:-}" \
--argjson checklist "''${3:-false}" \
--arg attr "$1"
exit "''${PIPESTATUS[0]}" # inherit exit code from cargo-audit
'';
tree-lock-file-report = depot.nix.writeExecline "tree-lock-file-report"
{
readNArgs = 1;
} [
"backtick"
"-E"
"report"
[
"pipeline"
[ bins.find "$1" "-name" "Cargo.lock" "-and" "-type" "f" "-print0" ]
"forstdin"
"-E"
"-0"
"lockFile"
"backtick"
"-E"
"depotPath"
[
"pipeline"
[ bins.s6-dirname "$lockFile" ]
bins.sed
"s|^\\.|/|"
]
lock-file-report
"$depotPath"
"$lockFile"
"false"
]
"if"
[ bins.printf "%s\n" "$report" ]
# empty report implies success (no advisories)
bins.s6-test
"-z"
"$report"
];
check-all-our-lock-files = depot.nix.writeExecline "check-all-our-lock-files" { } [
"backtick"
"-EI"
"report"
[
"foreground"
[
lock-file-report
"//third_party/rust-crates"
our-crates-lock-file
"false"
]
tree-lock-file-report
"."
]
"ifelse"
[
bins.s6-test
"-z"
"$report"
]
[
"exit"
"0"
]
"pipeline"
[
"printf"
"%s"
"$report"
]
"buildkite-agent"
"annotate"
"--style"
"warning"
"--context"
"check-all-our-lock-files"
];
in
depot.nix.readTree.drvTargets {
inherit
test-parsing-all-security-advisories
check-crate-advisory
lock-file-report
;
tree-lock-file-report = tree-lock-file-report // {
meta.ci.extraSteps.run = {
label = "Check all crates used in depot for advisories";
alwaysRun = true;
command = check-all-our-lock-files;
};
};
}