diff --git a/Cargo.lock b/Cargo.lock index 4ce8bca..54cd7be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -367,6 +367,7 @@ dependencies = [ "bin-lib", "clap", "fw-lib", + "semver", "serde", "serde_json", "verify-lib", diff --git a/common/bin/src/binary.rs b/common/bin/src/binary.rs index 6cfe1a1..97e30bd 100644 --- a/common/bin/src/binary.rs +++ b/common/bin/src/binary.rs @@ -6,7 +6,7 @@ use elf::{abi, ElfStream}; use crate::BinaryInfo; impl BinaryInfo { - pub fn parse(source: S, name: N) -> Result + pub fn parse(source: S, name: N, with_rpath: bool) -> Result where S: std::io::Read + std::io::Seek, N: AsRef, @@ -29,13 +29,17 @@ impl BinaryInfo { dynstr_table.get(entry.d_val() as usize).unwrap(), )); } - abi::DT_RPATH | abi::DT_RUNPATH => rpath.extend( - dynstr_table - .get(entry.d_val() as usize) - .unwrap() - .split(":") - .map(|s| String::from(s)), - ), + abi::DT_RPATH | abi::DT_RUNPATH => { + if with_rpath { + rpath.extend( + dynstr_table + .get(entry.d_val() as usize) + .unwrap() + .split(":") + .map(|s| String::from(s)), + ) + } + } _ => {} } } @@ -89,7 +93,7 @@ mod tests { fn test_parse() { let mut content = Cursor::new(include_bytes!("fixtures/sample.bin")); let info = - BinaryInfo::parse(&mut content, "sample.bin").expect("should not have any error"); + BinaryInfo::parse(&mut content, "sample.bin", true).expect("should not have any error"); assert_eq!(info.needed[0], "libc.so.6"); } } diff --git a/common/ipk/src/component.rs b/common/ipk/src/component.rs index ef69de8..f45a953 100644 --- a/common/ipk/src/component.rs +++ b/common/ipk/src/component.rs @@ -56,6 +56,7 @@ impl Component { ) })?, exe_path.file_name().unwrap().to_string_lossy(), + true, ) .map_err(|e| { Error::new( @@ -94,6 +95,7 @@ impl Component { let bin_info = BinaryInfo::parse( File::open(dir.join(&exe_path))?, exe_path.file_name().unwrap().to_string_lossy(), + true, ) .map_err(|e| { Error::new( diff --git a/packages/elf-verify/Cargo.toml b/packages/elf-verify/Cargo.toml index 79b90a4..f59c9f7 100644 --- a/packages/elf-verify/Cargo.toml +++ b/packages/elf-verify/Cargo.toml @@ -9,6 +9,7 @@ license = "Apache-2.0" [dependencies] serde = "1.0.183" serde_json = "1.0.96" +semver = "1.0.18" [dependencies.clap] version = "4.3.23" diff --git a/packages/elf-verify/src/main.rs b/packages/elf-verify/src/main.rs index 7f06adc..3a248f0 100644 --- a/packages/elf-verify/src/main.rs +++ b/packages/elf-verify/src/main.rs @@ -1,8 +1,10 @@ use std::fs::File; use std::path::PathBuf; -use bin_lib::BinaryInfo; use clap::Parser; +use semver::VersionReq; + +use bin_lib::BinaryInfo; use fw_lib::Firmware; use verify_lib::Verify; @@ -12,26 +14,57 @@ struct Args { executables: Vec, #[arg(short, long, num_args(1..))] lib_paths: Vec, + #[arg(short = 'R', long, default_value = "false")] + skip_rpath: bool, + #[arg(short = 'r', long)] + fw_releases: Option, #[arg(short, long, action = clap::ArgAction::Count)] debug: u8, } fn main() { let args = Args::parse(); + let firmwares: Vec = Firmware::list(Firmware::data_path()) + .unwrap() + .into_iter() + .filter(|fw| { + if let Some(fw_releases) = &args.fw_releases { + return fw_releases.matches(&fw.info.release); + } + return true; + }) + .collect(); + if firmwares.is_empty() { + eprintln!("No firmware found"); + return; + } for executable in args.executables { let Ok(file) = File::open(&executable) else { eprintln!("Failed to open file {}", executable.to_string_lossy()); continue; }; - let mut info = BinaryInfo::parse(file, executable.file_name().unwrap().to_string_lossy()) - .expect("parse error"); + let mut info = BinaryInfo::parse( + file, + executable.file_name().unwrap().to_string_lossy(), + !args.skip_rpath, + ) + .expect("parse error"); info.rpath.extend(args.lib_paths.clone()); - for firmware in Firmware::list(Firmware::data_path()).unwrap() { - println!( - "Verify result for firmware {} {:?}", - firmware.info, - info.verify(&|name| firmware.find_library(name)) - ); + let mut all_ok = true; + for firmware in &firmwares { + let result = info.verify(&|name| firmware.find_library(name)); + println!("Verify result for firmware {}:", firmware.info); + for lib in result.missing_lib { + println!("Missing library: {}", lib); + all_ok = false; + } + for sym in result.undefined_sym { + println!("Missing symbol: {}", sym); + all_ok = false; + } + } + if all_ok { + println!("All OK."); } } }