From c5b6c57c34f89d865e07939eff67d6687e9339e2 Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Tue, 14 Apr 2020 15:21:42 -0500 Subject: [PATCH] Check .debug_str data that is not from DWARF (#1507) * Check .debug_str data that is not from DWARF * xplatform check --- crates/debug/src/transform/simulate.rs | 55 ++++++++++++++++++++------ tests/debug/simulate.rs | 22 +++++++++++ 2 files changed, 66 insertions(+), 11 deletions(-) diff --git a/crates/debug/src/transform/simulate.rs b/crates/debug/src/transform/simulate.rs index baf76e640b..ec70dec4ea 100644 --- a/crates/debug/src/transform/simulate.rs +++ b/crates/debug/src/transform/simulate.rs @@ -16,6 +16,18 @@ use wasmtime_environ::isa::TargetIsa; const PRODUCER_NAME: &str = "wasmtime"; +macro_rules! assert_dwarf_str { + ($s:expr) => {{ + let s = $s; + if cfg!(debug_assertions) { + // Perform check the same way as gimli does it. + let bytes: Vec = s.clone().into(); + debug_assert!(!bytes.contains(&0), "DWARF string shall not have NULL byte"); + } + s + }}; +} + fn generate_line_info( addr_tr: &AddressTransform, translated: &HashSet, @@ -75,11 +87,20 @@ fn generate_line_info( Ok(out_program) } +fn check_invalid_chars_in_name(s: String) -> Option { + if s.contains('\x00') { + None + } else { + Some(s) + } +} + fn autogenerate_dwarf_wasm_path(di: &DebugInfoData) -> PathBuf { let module_name = di .name_section .as_ref() .and_then(|ns| ns.module_name.to_owned()) + .and_then(check_invalid_chars_in_name) .unwrap_or_else(|| unsafe { static mut GEN_ID: u32 = 0; GEN_ID += 1; @@ -233,8 +254,11 @@ fn generate_vars( ); let var = unit.get_mut(var_id); - let name_id = match locals_names.and_then(|m| m.get(&(var_index as u32))) { - Some(n) => out_strings.add(n.to_owned()), + let name_id = match locals_names + .and_then(|m| m.get(&(var_index as u32))) + .and_then(|s| check_invalid_chars_in_name(s.to_owned())) + { + Some(n) => out_strings.add(assert_dwarf_str!(n)), None => out_strings.add(format!("var{}", var_index)), }; @@ -252,6 +276,12 @@ fn generate_vars( Ok(()) } +fn check_invalid_chars_in_path(path: PathBuf) -> Option { + path.clone() + .to_str() + .and_then(move |s| if s.contains('\x00') { None } else { Some(path) }) +} + pub fn generate_simulated_dwarf( addr_tr: &AddressTransform, di: &DebugInfoData, @@ -267,6 +297,7 @@ pub fn generate_simulated_dwarf( .wasm_file .path .to_owned() + .and_then(check_invalid_chars_in_path) .unwrap_or_else(|| autogenerate_dwarf_wasm_path(di)); let (func_names, locals_names) = if let Some(ref name_section) = di.name_section { @@ -280,18 +311,17 @@ pub fn generate_simulated_dwarf( let imported_func_count = di.wasm_file.imported_func_count; let (unit, root_id, name_id) = { - let comp_dir_id = out_strings.add( - path.parent() - .context("path dir")? - .to_str() - .context("path dir encoding")?, - ); + let comp_dir_id = out_strings.add(assert_dwarf_str!(path + .parent() + .context("path dir")? + .to_str() + .context("path dir encoding")?)); let name = path .file_name() .context("path name")? .to_str() .context("path name encoding")?; - let name_id = out_strings.add(name); + let name_id = out_strings.add(assert_dwarf_str!(name)); let out_program = generate_line_info( addr_tr, @@ -348,8 +378,11 @@ pub fn generate_simulated_dwarf( ); let func_index = imported_func_count + (index as u32); - let id = match func_names.and_then(|m| m.get(&func_index)) { - Some(n) => out_strings.add(n.to_owned()), + let id = match func_names + .and_then(|m| m.get(&func_index)) + .and_then(|s| check_invalid_chars_in_name(s.to_owned())) + { + Some(n) => out_strings.add(assert_dwarf_str!(n)), None => out_strings.add(format!("wasm-function[{}]", func_index)), }; diff --git a/tests/debug/simulate.rs b/tests/debug/simulate.rs index b727b46acd..4ed9f9847c 100644 --- a/tests/debug/simulate.rs +++ b/tests/debug/simulate.rs @@ -75,3 +75,25 @@ fn test_debug_dwarf_simulate_with_imports_x86_64() -> Result<()> { )"#, ) } + +#[test] +#[ignore] +#[cfg(all( + any(target_os = "linux", target_os = "macos"), + target_pointer_width = "64" +))] +fn test_debug_dwarf_simulate_with_invalid_name_x86_64() -> Result<()> { + check_wat( + r#" +;; check: DW_TAG_compile_unit +(module (@name "\00") +;; check: DW_TAG_subprogram +;; check: DW_AT_name ("wasm-function[1]") + (import "foo" "bar" (func $import1) ) + (func (@name "\00f") (result i32) + (local (@name "l\00") i32) + i32.const 1 + ) +)"#, + ) +}