From 9822fa387ae8d8053eaba1b30c3fc5870ba701b8 Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Tue, 17 Jan 2023 13:31:31 +0100 Subject: feat(tvix/derivation): more checks for output hashes and encoding Change-Id: Idebad60c3bf9daf94d04a36bb73ac0dd767f9e79 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7856 Reviewed-by: tazjin Tested-by: BuildkiteCI --- tvix/Cargo.lock | 1 + tvix/Cargo.nix | 4 ++++ tvix/derivation/Cargo.toml | 1 + tvix/derivation/src/errors.rs | 6 ++++++ tvix/derivation/src/output.rs | 23 +++++++++++++++++++++-- 5 files changed, 33 insertions(+), 2 deletions(-) diff --git a/tvix/Cargo.lock b/tvix/Cargo.lock index 523264b32f84..acf516900fd6 100644 --- a/tvix/Cargo.lock +++ b/tvix/Cargo.lock @@ -2318,6 +2318,7 @@ name = "tvix-derivation" version = "0.1.0" dependencies = [ "anyhow", + "data-encoding", "glob", "serde", "serde_json", diff --git a/tvix/Cargo.nix b/tvix/Cargo.nix index ca3165c1afab..cb86a7fe5ba7 100644 --- a/tvix/Cargo.nix +++ b/tvix/Cargo.nix @@ -6879,6 +6879,10 @@ rec { name = "anyhow"; packageId = "anyhow"; } + { + name = "data-encoding"; + packageId = "data-encoding"; + } { name = "glob"; packageId = "glob"; diff --git a/tvix/derivation/Cargo.toml b/tvix/derivation/Cargo.toml index 12afcf92c1e8..ff54a0848abe 100644 --- a/tvix/derivation/Cargo.toml +++ b/tvix/derivation/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] anyhow = "1.0.68" +data-encoding = "2.3.3" glob = "0.3.0" serde = { version = "1.0", features = ["derive"] } sha2 = "0.10.6" diff --git a/tvix/derivation/src/errors.rs b/tvix/derivation/src/errors.rs index 75b101efddae..6942967e1d23 100644 --- a/tvix/derivation/src/errors.rs +++ b/tvix/derivation/src/errors.rs @@ -47,4 +47,10 @@ pub enum DerivationError { pub enum OutputError { #[error("Invalid ouput path {0}: {1}")] InvalidOutputPath(String, ParseStorePathError), + #[error("Invalid hash encoding: {0}")] + InvalidHashEncoding(String, data_encoding::DecodeError), + #[error("Invalid hash algo: {0}")] + InvalidHashAlgo(String), + #[error("Invalid Digest size {0} for algo {1}")] + InvalidDigestSizeForAlgo(usize, String), } diff --git a/tvix/derivation/src/output.rs b/tvix/derivation/src/output.rs index 369efca031f3..36a480d5a0d7 100644 --- a/tvix/derivation/src/output.rs +++ b/tvix/derivation/src/output.rs @@ -1,5 +1,5 @@ use serde::{Deserialize, Serialize}; -use tvix_store::store_path::StorePath; +use tvix_store::{nixbase32::NIXBASE32, store_path::StorePath}; use crate::OutputError; @@ -25,7 +25,26 @@ impl Output { } pub fn validate(&self, validate_output_paths: bool) -> Result<(), OutputError> { - // TODO: add validation for hash, hashAlgo + if let Some(hash) = &self.hash { + // try to decode digest + let result = NIXBASE32.decode(&hash.digest.as_bytes()); + match result { + Err(e) => return Err(OutputError::InvalidHashEncoding(hash.digest.clone(), e)), + Ok(digest) => { + if hash.algo != "sha1" && hash.algo != "sha256" { + return Err(OutputError::InvalidHashAlgo(hash.algo.to_string())); + } + if (hash.algo == "sha1" && digest.len() != 20) + || (hash.algo == "sha256" && digest.len() != 32) + { + return Err(OutputError::InvalidDigestSizeForAlgo( + digest.len(), + hash.algo.to_string(), + )); + } + } + }; + } if validate_output_paths { if let Err(e) = StorePath::from_absolute_path(&self.path) { return Err(OutputError::InvalidOutputPath(self.path.to_string(), e)); -- cgit 1.4.1