1use std::io::{BufRead, Read}; 2use std::{fs, io}; 3 4use rustix::thread::*; 5 6#[test] 7fn test_get_keep_capabilities() { 8 dbg!(get_keep_capabilities().unwrap()); 9} 10 11#[test] 12fn test_name() { 13 dbg!(name().unwrap()); 14} 15 16#[test] 17fn test_is_in_capability_bounding_set() { 18 dbg!(is_in_capability_bounding_set(Capability::ChangeOwnership).unwrap()); 19} 20 21#[test] 22fn test_capabilities_secure_bits() { 23 dbg!(capabilities_secure_bits().unwrap()); 24} 25 26#[test] 27fn test_current_timer_slack() { 28 dbg!(current_timer_slack().unwrap()); 29} 30 31#[test] 32fn test_no_new_privs() { 33 dbg!(no_new_privs().unwrap()); 34} 35 36#[test] 37fn test_capability_is_in_ambient_capability_set() { 38 dbg!(capability_is_in_ambient_capability_set(Capability::ChangeOwnership).unwrap()); 39} 40 41#[cfg(target_arch = "aarch64")] 42#[test] 43fn test_sve_vector_length_configuration() { 44 dbg!(sve_vector_length_configuration().unwrap()); 45} 46 47#[cfg(target_arch = "aarch64")] 48#[test] 49fn test_current_tagged_address_mode() { 50 dbg!(current_tagged_address_mode().unwrap()); 51} 52 53#[test] 54#[ignore = "?"] 55fn test_transparent_huge_pages_are_disabled() { 56 dbg!(transparent_huge_pages_are_disabled().unwrap()); 57} 58 59/* 60#[test] 61#[ignore = "Might result in SIGKILL"] 62fn test_secure_computing_mode() { 63 if !linux_kernel_config_item_is_enabled("CONFIG_SECCOMP").unwrap_or(false) { 64 eprintln!("test_secure_computing_mode: Test skipped due to missing kernel feature: CONFIG_SECCOMP."); 65 return; 66 } 67 68 dbg!(secure_computing_mode().unwrap()); 69} 70*/ 71 72#[test] 73fn test_get_clear_child_tid_address() { 74 if !linux_kernel_config_item_is_enabled("CONFIG_CHECKPOINT_RESTORE").unwrap_or(false) { 75 eprintln!("test_get_clear_child_tid_address: Test skipped due to missing kernel feature: CONFIG_CHECKPOINT_RESTORE."); 76 return; 77 } 78 79 match get_clear_child_tid_address() { 80 Ok(address) => println!("get_clear_child_tid_address = {:?}", address), 81 82 Err(r) => { 83 let errno = r.raw_os_error(); 84 assert!(errno == libc::ENODEV || errno == libc::EINVAL); 85 eprintln!("test_get_clear_child_tid_address: Test unsupported: {}", r); 86 } 87 } 88} 89 90#[test] 91fn test_core_scheduling_cookie() { 92 if !linux_kernel_config_item_is_enabled("CONFIG_SCHED_CORE").unwrap_or(false) { 93 eprintln!("test_core_scheduling_cookie: Test skipped due to missing kernel feature: CONFIG_SCHED_CORE."); 94 return; 95 } 96 97 match core_scheduling_cookie(rustix::thread::gettid(), CoreSchedulingScope::Thread) { 98 Ok(cookie) => println!("core_scheduling_cookie = {:?}", cookie), 99 100 Err(r) => { 101 let errno = r.raw_os_error(); 102 assert!(errno == libc::ENODEV || errno == libc::EINVAL); 103 eprintln!("test_core_scheduling_cookie: Test unsupported: {}", r); 104 } 105 } 106} 107 108/* 109 * Helper functions. 110 */ 111 112fn load_linux_kernel_config() -> io::Result<Vec<u8>> { 113 if let Ok(compressed_bytes) = fs::read("/proc/config.gz") { 114 let mut decoder = flate2::bufread::GzDecoder::new(compressed_bytes.as_slice()); 115 let mut bytes = Vec::default(); 116 decoder.read_to_end(&mut bytes)?; 117 return Ok(bytes); 118 } 119 120 let info = rustix::process::uname(); 121 let release = info 122 .release() 123 .to_str() 124 .map_err(|_r| io::Error::from(io::ErrorKind::InvalidData))?; 125 126 fs::read(format!("/boot/config-{}", release)) 127} 128 129fn is_linux_kernel_config_item_enabled(config: &[u8], name: &str) -> io::Result<bool> { 130 for line in io::Cursor::new(config).lines() { 131 let line = line?; 132 let line = line.trim(); 133 if line.is_empty() || line.starts_with('#') { 134 continue; 135 } 136 137 let mut iter = line.splitn(2, '='); 138 if let Some(current_name) = iter.next().map(str::trim) { 139 if current_name == name { 140 if let Some(mut value) = iter.next().map(str::trim) { 141 if value.starts_with('"') && value.ends_with('"') { 142 // Just remove the quotes, but don't bother unescaping the inner string 143 // because we are only trying to find out if the option is an true boolean. 144 value = &value[1..(value.len() - 2)]; 145 } 146 147 return Ok(value == "y" || value == "m"); 148 } 149 } 150 } 151 } 152 Ok(false) 153} 154 155pub(crate) fn linux_kernel_config_item_is_enabled(name: &str) -> io::Result<bool> { 156 let config = load_linux_kernel_config()?; 157 is_linux_kernel_config_item_enabled(&config, name) 158} 159