diff --git a/cranelift/object/src/backend.rs b/cranelift/object/src/backend.rs index 81dd75c4cd..98ab139a2f 100644 --- a/cranelift/object/src/backend.rs +++ b/cranelift/object/src/backend.rs @@ -145,6 +145,18 @@ impl ObjectModule { } } +fn validate_symbol(name: &str) -> ModuleResult<()> { + // null bytes are not allowed in symbol names and will cause the `object` + // crate to panic. Let's return a clean error instead. + if name.contains("\0") { + return Err(ModuleError::Backend(anyhow::anyhow!( + "Symbol {:?} has a null byte, which is disallowed", + name + ))); + } + Ok(()) +} + impl Module for ObjectModule { fn isa(&self) -> &dyn TargetIsa { &*self.isa @@ -160,6 +172,8 @@ impl Module for ObjectModule { linkage: Linkage, signature: &ir::Signature, ) -> ModuleResult { + validate_symbol(name)?; + let (id, decl) = self .declarations .declare_function(name, linkage, signature)?; @@ -194,6 +208,8 @@ impl Module for ObjectModule { writable: bool, tls: bool, ) -> ModuleResult { + validate_symbol(name)?; + let (id, decl) = self .declarations .declare_data(name, linkage, writable, tls)?; diff --git a/cranelift/object/tests/basic.rs b/cranelift/object/tests/basic.rs index 18acae5733..dad2bbca9d 100644 --- a/cranelift/object/tests/basic.rs +++ b/cranelift/object/tests/basic.rs @@ -197,3 +197,46 @@ fn libcall_function() { module.finish(); } + +#[test] +#[should_panic( + expected = "Result::unwrap()` on an `Err` value: Backend(Symbol \"function\\u{0}with\\u{0}nul\\u{0}bytes\" has a null byte, which is disallowed" +)] +fn reject_nul_byte_symbol_for_func() { + let flag_builder = settings::builder(); + let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap(); + let isa = isa_builder.finish(settings::Flags::new(flag_builder)); + let mut module = + ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap()); + + let sig = Signature { + params: vec![], + returns: vec![], + call_conv: CallConv::SystemV, + }; + + let _ = module + .declare_function("function\u{0}with\u{0}nul\u{0}bytes", Linkage::Local, &sig) + .unwrap(); +} + +#[test] +#[should_panic( + expected = "Result::unwrap()` on an `Err` value: Backend(Symbol \"data\\u{0}with\\u{0}nul\\u{0}bytes\" has a null byte, which is disallowed" +)] +fn reject_nul_byte_symbol_for_data() { + let flag_builder = settings::builder(); + let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap(); + let isa = isa_builder.finish(settings::Flags::new(flag_builder)); + let mut module = + ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap()); + + let _ = module + .declare_data( + "data\u{0}with\u{0}nul\u{0}bytes", + Linkage::Local, + /* writable = */ true, + /* tls = */ false, + ) + .unwrap(); +}