Check .debug_str data that is not from DWARF (#1507)

* Check .debug_str data that is not from DWARF

* xplatform check
This commit is contained in:
Yury Delendik
2020-04-14 15:21:42 -05:00
committed by GitHub
parent 27bee2a1a8
commit c5b6c57c34
2 changed files with 66 additions and 11 deletions

View File

@@ -16,6 +16,18 @@ use wasmtime_environ::isa::TargetIsa;
const PRODUCER_NAME: &str = "wasmtime"; 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<u8> = s.clone().into();
debug_assert!(!bytes.contains(&0), "DWARF string shall not have NULL byte");
}
s
}};
}
fn generate_line_info( fn generate_line_info(
addr_tr: &AddressTransform, addr_tr: &AddressTransform,
translated: &HashSet<DefinedFuncIndex>, translated: &HashSet<DefinedFuncIndex>,
@@ -75,11 +87,20 @@ fn generate_line_info(
Ok(out_program) Ok(out_program)
} }
fn check_invalid_chars_in_name(s: String) -> Option<String> {
if s.contains('\x00') {
None
} else {
Some(s)
}
}
fn autogenerate_dwarf_wasm_path(di: &DebugInfoData) -> PathBuf { fn autogenerate_dwarf_wasm_path(di: &DebugInfoData) -> PathBuf {
let module_name = di let module_name = di
.name_section .name_section
.as_ref() .as_ref()
.and_then(|ns| ns.module_name.to_owned()) .and_then(|ns| ns.module_name.to_owned())
.and_then(check_invalid_chars_in_name)
.unwrap_or_else(|| unsafe { .unwrap_or_else(|| unsafe {
static mut GEN_ID: u32 = 0; static mut GEN_ID: u32 = 0;
GEN_ID += 1; GEN_ID += 1;
@@ -233,8 +254,11 @@ fn generate_vars(
); );
let var = unit.get_mut(var_id); let var = unit.get_mut(var_id);
let name_id = match locals_names.and_then(|m| m.get(&(var_index as u32))) { let name_id = match locals_names
Some(n) => out_strings.add(n.to_owned()), .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)), None => out_strings.add(format!("var{}", var_index)),
}; };
@@ -252,6 +276,12 @@ fn generate_vars(
Ok(()) Ok(())
} }
fn check_invalid_chars_in_path(path: PathBuf) -> Option<PathBuf> {
path.clone()
.to_str()
.and_then(move |s| if s.contains('\x00') { None } else { Some(path) })
}
pub fn generate_simulated_dwarf( pub fn generate_simulated_dwarf(
addr_tr: &AddressTransform, addr_tr: &AddressTransform,
di: &DebugInfoData, di: &DebugInfoData,
@@ -267,6 +297,7 @@ pub fn generate_simulated_dwarf(
.wasm_file .wasm_file
.path .path
.to_owned() .to_owned()
.and_then(check_invalid_chars_in_path)
.unwrap_or_else(|| autogenerate_dwarf_wasm_path(di)); .unwrap_or_else(|| autogenerate_dwarf_wasm_path(di));
let (func_names, locals_names) = if let Some(ref name_section) = di.name_section { 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 imported_func_count = di.wasm_file.imported_func_count;
let (unit, root_id, name_id) = { let (unit, root_id, name_id) = {
let comp_dir_id = out_strings.add( let comp_dir_id = out_strings.add(assert_dwarf_str!(path
path.parent() .parent()
.context("path dir")? .context("path dir")?
.to_str() .to_str()
.context("path dir encoding")?, .context("path dir encoding")?));
);
let name = path let name = path
.file_name() .file_name()
.context("path name")? .context("path name")?
.to_str() .to_str()
.context("path name encoding")?; .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( let out_program = generate_line_info(
addr_tr, addr_tr,
@@ -348,8 +378,11 @@ pub fn generate_simulated_dwarf(
); );
let func_index = imported_func_count + (index as u32); let func_index = imported_func_count + (index as u32);
let id = match func_names.and_then(|m| m.get(&func_index)) { let id = match func_names
Some(n) => out_strings.add(n.to_owned()), .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)), None => out_strings.add(format!("wasm-function[{}]", func_index)),
}; };

View File

@@ -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
)
)"#,
)
}