Skip to content

Commit

Permalink
feat(scan): support scanning the portage tree/kits of ebuilds [#29]
Browse files Browse the repository at this point in the history
  • Loading branch information
mrl5 committed Mar 5, 2022
1 parent 436f0e9 commit 338cbf0
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 22 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Discover CVEs for software.
- **Use case 1)** as a [Funtoo Linux] user I want to have awareness about CVEs on my system
- **Use case 2)** as user I want to list CVEs for given package
- **Use case 3)** as a [Gentoo Linux] user I want to have awareness about CVEs on my system
- **Use case 4)** as a [Funtoo Linux] maintainer I want to scan all packages in kit for CVEs

## DISCLAIMER

Expand Down
4 changes: 4 additions & 0 deletions crates/cli/src/command/scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ pub async fn execute(
let known_exploited_cves = fetch_known_exploited_cves(&client).await?;

for (ctg, pkgs) in catpkgs {
if pkgs.len() == 0 {
continue;
}

let cwd = out_dir.join(&ctg);
log::debug!("processing {} ...", ctg);
handle_pkgs(&client, &feed, &cwd, &ctg, &pkgs, &known_exploited_cves).await?;
Expand Down
1 change: 1 addition & 0 deletions crates/cpe-tag/python/integrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def run(payload: list) -> str:


def handle_list(packages: list) -> list:
assert len(packages) > 0, "expected non empty list"
cpe_patterns = []
for package in packages:
cpe_patterns = cpe_patterns + handle_dict(package)
Expand Down
68 changes: 46 additions & 22 deletions crates/os-adapter/src/adapter/portage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use cpe_tag::package::{convert_to_pkg, Package};
use std::collections::HashMap;
use std::error::Error;
use std::fs::read_dir;
use std::fs::{read_dir, DirEntry};
use std::path::{Path, PathBuf};

pub trait Portage {
Expand All @@ -28,7 +28,7 @@ where
fn get_all_catpkgs(&self) -> Result<HashMap<String, Vec<Package>>, Box<dyn Error>> {
let pkg_prefix_adapter: HashMap<&str, String> =
HashMap::from([("dev-libs", "lib".to_owned())]);
let skipped_dirs = vec!["virtual"];
let skipped_dirs = vec!["eclass", "licenses", "metadata", "profiles", "virtual"];
let mut all_catpkgs = HashMap::new();

if !&self.get_pkg_dir().exists() {
Expand All @@ -39,21 +39,21 @@ where

for category in read_dir(&self.get_pkg_dir())? {
let category = category?;
let path = &category.path();
let cat_path = &category.path();

if !path.is_dir() {
if !cat_path.is_dir() {
continue;
}

match category.file_name().into_string() {
Ok(ctgr) => {
if skipped_dirs.contains(&ctgr.as_str()) {
if skipped_dirs.contains(&ctgr.as_str()) || ctgr.starts_with('.') {
log::debug!("SKIPPING packages in {} ...", ctgr);
continue;
}

log::debug!("collecting packages in {} ...", ctgr);
let pkgs = list_pkgs(path, pkg_prefix_adapter.get(ctgr.as_str()))?;
let pkgs = list_pkgs(cat_path, pkg_prefix_adapter.get(ctgr.as_str()))?;
all_catpkgs.insert(ctgr, pkgs);
}
Err(os_path) => {
Expand All @@ -72,30 +72,54 @@ fn list_pkgs(path: &Path, prefix: Option<&String>) -> Result<Vec<Package>, Box<d

for pkg in read_dir(path)? {
let pkg = pkg?;
let path = &pkg.path();
let pkg_path = &pkg.path();
if !pkg_path.is_dir() {
continue;
}
push_pkgs(pkg_path, prefix, &mut pkgs)?;
}

Ok(pkgs)
}

if !path.is_dir() {
fn push_pkgs(
path: &Path,
prefix: Option<&String>,
pkgs: &mut Vec<Package>,
) -> Result<(), Box<dyn Error>> {
for entry in read_dir(path)? {
let entry = entry?;
if !is_ebuild(&entry) {
continue;
}

match pkg.file_name().into_string() {
Ok(p) => {
if let Some(converted) = convert_to_pkg(&p) {
pkgs.push(converted);
}
if let Ok(ebuild) = entry.file_name().into_string() {
let pkg: Vec<&str> = ebuild.rsplit(".ebuild").collect();
let pkg = pkg[1].to_owned();
if let Some(converted) = convert_to_pkg(&pkg) {
pkgs.push(converted);
}

if let Some(prfx) = prefix {
if let Some(converted) = convert_to_pkg(&format!("{}{}", prfx, &p)) {
pkgs.push(converted);
}
if let Some(prfx) = prefix {
if let Some(converted) = convert_to_pkg(&format!("{}{}", prfx, &pkg)) {
pkgs.push(converted);
}
}
Err(os_string) => {
log::error!("skipping {:?}", os_string);
continue;
}
}
}

Ok(pkgs)
Ok(())
}

fn is_ebuild(entry: &DirEntry) -> bool {
if !entry.path().is_file() {
return false;
}

if let Ok(file_name) = entry.file_name().into_string() {
return file_name.ends_with(".ebuild");
}

log::error!("malformed file name {:?}", entry.file_name());
false
}
14 changes: 14 additions & 0 deletions docs/COOKBOOK.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ vulner --help
- [Scanning Funtoo Linux system for CVEs](#scanning-funtoo-linux-system-for-cves)
- [Listing CVEs for given packages](#listing-cves-for-given-packages)
- [Printing known exploited vulnerabilities catalog](#printing-known-exploited-vulnerabilities-catalog)
- [Scanning packages in Funtoo Linux kit for CVEs](#scanning-packages-in-funtoo-linux-kit-for-cves)


## Scanning Funtoo Linux system for CVEs
Expand Down Expand Up @@ -57,6 +58,19 @@ $ cat ~/vulner/scan-results/2022-01-30UTC/*/app-emulation/*containerd*.txt | jq
```


## Scanning packages in Funtoo Linux kit for CVEs
```bash
kit="gnome-kit"

export VULNER_FEED_DIR=$HOME/vulner/feeds/json
export VULNER_OUT_DIR=$HOME/vulner/${kit}-scan-results
export RUST_LOG=info

vulner sync
vulner scan -p /var/git/meta-repo/kits/${kit}/
```


## Listing CVEs for given packages

### Example 1
Expand Down

0 comments on commit 338cbf0

Please sign in to comment.