cranelift-object: reject symbol names with NUL byte without panic'ing.
Avoid a `panic!()`, and return a proper error, on a NUL byte. We hit a null-byte check inside the `object` crate otherwise; this blocks fuzzing when testing via a write-object-file-and-dlopen flow.
This commit is contained in:
@@ -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 {
|
impl Module for ObjectModule {
|
||||||
fn isa(&self) -> &dyn TargetIsa {
|
fn isa(&self) -> &dyn TargetIsa {
|
||||||
&*self.isa
|
&*self.isa
|
||||||
@@ -160,6 +172,8 @@ impl Module for ObjectModule {
|
|||||||
linkage: Linkage,
|
linkage: Linkage,
|
||||||
signature: &ir::Signature,
|
signature: &ir::Signature,
|
||||||
) -> ModuleResult<FuncId> {
|
) -> ModuleResult<FuncId> {
|
||||||
|
validate_symbol(name)?;
|
||||||
|
|
||||||
let (id, decl) = self
|
let (id, decl) = self
|
||||||
.declarations
|
.declarations
|
||||||
.declare_function(name, linkage, signature)?;
|
.declare_function(name, linkage, signature)?;
|
||||||
@@ -194,6 +208,8 @@ impl Module for ObjectModule {
|
|||||||
writable: bool,
|
writable: bool,
|
||||||
tls: bool,
|
tls: bool,
|
||||||
) -> ModuleResult<DataId> {
|
) -> ModuleResult<DataId> {
|
||||||
|
validate_symbol(name)?;
|
||||||
|
|
||||||
let (id, decl) = self
|
let (id, decl) = self
|
||||||
.declarations
|
.declarations
|
||||||
.declare_data(name, linkage, writable, tls)?;
|
.declare_data(name, linkage, writable, tls)?;
|
||||||
|
|||||||
@@ -197,3 +197,46 @@ fn libcall_function() {
|
|||||||
|
|
||||||
module.finish();
|
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();
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user