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";
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(
addr_tr: &AddressTransform,
translated: &HashSet<DefinedFuncIndex>,
@@ -75,11 +87,20 @@ fn generate_line_info(
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 {
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<PathBuf> {
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()
let comp_dir_id = out_strings.add(assert_dwarf_str!(path
.parent()
.context("path dir")?
.to_str()
.context("path dir encoding")?,
);
.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)),
};

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