From fa3abec50537f2776d6745fd4be0928118ebd2b2 Mon Sep 17 00:00:00 2001 From: Sean McGinnis Date: Thu, 2 Nov 2023 18:51:38 +0000 Subject: [PATCH] cis: Improve UDF kernel module check The level 2 check 1.1.1.1 verifies mounting UDF filesystems is disabled. The current check for whether it is already loaded was not correct. Luckily there is a second check as part of this control to make sure loading is disabled. If the setting for loading is to not allow it, but the module is already loaded, the check does not return the expected output. So it would still report failure, but it is less than ideal for reporting the actual issue. This changes the check for whether the module is loaded to correctly identify if the module is loaded or not before checking whether the ability has been disabled. Signed-off-by: Sean McGinnis --- .../src/bin/bottlerocket-checks/checks.rs | 21 ++++-- sources/bloodhound/src/lib.rs | 67 +++++++++++++++++++ 2 files changed, 81 insertions(+), 7 deletions(-) diff --git a/sources/bloodhound/src/bin/bottlerocket-checks/checks.rs b/sources/bloodhound/src/bin/bottlerocket-checks/checks.rs index 43b2bae959e..5d0889560b3 100644 --- a/sources/bloodhound/src/bin/bottlerocket-checks/checks.rs +++ b/sources/bloodhound/src/bin/bottlerocket-checks/checks.rs @@ -22,15 +22,22 @@ pub struct BR01010101Checker {} impl Checker for BR01010101Checker { fn execute(&self) -> CheckerResult { - let module_result = check_file_contains!( - PROC_MODULES_FILE, - &[" udf,"], - "unable to parse modules to check for udf", - "udf is currently loaded" - ); - if module_result.status != CheckStatus::PASS { + let mut module_result = CheckerResult::default(); + + // Make sure UDF isn't already loaded + if let Ok(found) = look_for_word_in_file(PROC_MODULES_FILE, "udf") { + if found { + module_result.error = "udf is currently loaded".to_string(); + module_result.status = CheckStatus::FAIL; + return module_result; + } + } else { + module_result.error = + "unable to parse modprobe output to check if udf is enabled".to_string(); return module_result; } + + // Make sure the ability to load UDF is disabled check_output_contains!( MODPROBE_CMD, ["-n", "-v", "udf"], diff --git a/sources/bloodhound/src/lib.rs b/sources/bloodhound/src/lib.rs index 870d0067afb..247e8403f32 100644 --- a/sources/bloodhound/src/lib.rs +++ b/sources/bloodhound/src/lib.rs @@ -9,6 +9,16 @@ pub mod args; pub mod output; pub mod results; +/// Reads a file and checks if the given `search_word` is present in its contents. +pub fn look_for_word_in_file(path: &str, search_word: &str) -> Result { + let reader = BufReader::new(File::open(path)?); + Ok(reader.lines().any(|line| { + line.unwrap_or_default() + .split_ascii_whitespace() + .any(|word| word == search_word) + })) +} + /// Reads a file and checks if the given `search_str` is present in its contents. pub fn look_for_string_in_file(path: &str, search_str: &str) -> Result { let reader = BufReader::new(File::open(path)?); @@ -197,6 +207,63 @@ mod test_utils { }}; } + #[test] + fn test_look_for_word_in_file_found() { + let mut test_file = NamedTempFile::new().unwrap(); + writeln!( + test_file, + concat!( + "udf 139264 0 - Live 0xffffffffc05e1000\n", + "crc_itu_t 16384 1 udf, Live 0xffffffffc05dc000\n", + "configfs 57344 1 - Live 0xffffffffc0320000\n" + ) + ) + .unwrap(); + + let found = look_for_word_in_file(temp_file_path!(test_file), "udf").unwrap(); + assert!(found); + } + + #[test] + fn test_look_for_word_in_file_not_found() { + let mut test_file = NamedTempFile::new().unwrap(); + writeln!( + test_file, + concat!( + "crypto_simd 16384 1 aesni_intel, Live 0xffffffffc034f000\n", + "cryptd 28672 2 ghash_clmulni_intel,crypto_simd, Live 0xffffffffc0335000\n", + "configfs 57344 1 - Live 0xffffffffc0320000\n" + ) + ) + .unwrap(); + + let found = look_for_word_in_file(temp_file_path!(test_file), "udf").unwrap(); + assert!(!found); + } + + #[test] + fn test_look_for_word_in_file_partial_not_found() { + let mut test_file = NamedTempFile::new().unwrap(); + writeln!( + test_file, + concat!( + "my-udf 139264 0 - Live 0xffffffffc05e1000\n", + "crc_itu_t 16384 1 udf, Live 0xffffffffc05dc000\n", + "configfs 57344 1 - Live 0xffffffffc0320000\n" + ) + ) + .unwrap(); + + let found = look_for_word_in_file(temp_file_path!(test_file), "udf").unwrap(); + assert!(!found); + } + + #[test] + fn test_look_for_word_in_file_bad_path() { + let result = look_for_word_in_file("/not/a/real/path", "search_str"); + assert!(result.is_err()); + } + #[test] fn test_string_in_file_found() { let mut test_file = NamedTempFile::new().unwrap();