make Module::deserialize's version check optional via Config (#2945)
* make Module::deserialize's version check optional via Config A SerializedModule contains the CARGO_PKG_VERSION string, which is checked for equality when loading. This is a great guard-rail but some users may want to disable this check (e.g. so they can implement their own versioning scheme) * rename config to deserialize_check_wasmtime_version * add test * fix doc links * fix * thank you rustdoc
This commit is contained in:
@@ -291,6 +291,7 @@ pub struct Config {
|
||||
#[cfg(feature = "async")]
|
||||
pub(crate) async_stack_size: usize,
|
||||
pub(crate) async_support: bool,
|
||||
pub(crate) deserialize_check_wasmtime_version: bool,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
@@ -326,6 +327,7 @@ impl Config {
|
||||
#[cfg(feature = "async")]
|
||||
async_stack_size: 2 << 20,
|
||||
async_support: false,
|
||||
deserialize_check_wasmtime_version: true,
|
||||
};
|
||||
ret.cranelift_debug_verifier(false);
|
||||
ret.cranelift_opt_level(OptLevel::Speed);
|
||||
@@ -1093,6 +1095,20 @@ impl Config {
|
||||
self
|
||||
}
|
||||
|
||||
/// Configure whether deserialized modules should validate version
|
||||
/// information. This only effects [`crate::Module::deserialize()`], which is
|
||||
/// used to load compiled code from trusted sources. When true,
|
||||
/// [`crate::Module::deserialize()`] verifies that the wasmtime crate's
|
||||
/// `CARGO_PKG_VERSION` matches with the version in the binary, which was
|
||||
/// produced by [`crate::Module::serialize`] or
|
||||
/// [`crate::Engine::precompile_module`].
|
||||
///
|
||||
/// This value defaults to true.
|
||||
pub fn deserialize_check_wasmtime_version(&mut self, check: bool) -> &mut Self {
|
||||
self.deserialize_check_wasmtime_version = check;
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn target_isa(&self) -> Box<dyn TargetIsa> {
|
||||
self.isa_flags
|
||||
.clone()
|
||||
|
||||
@@ -356,7 +356,10 @@ impl Module {
|
||||
/// blobs across versions of wasmtime you can be safely guaranteed that
|
||||
/// future versions of wasmtime will reject old cache entries).
|
||||
pub unsafe fn deserialize(engine: &Engine, bytes: impl AsRef<[u8]>) -> Result<Module> {
|
||||
let module = SerializedModule::from_bytes(bytes.as_ref())?;
|
||||
let module = SerializedModule::from_bytes(
|
||||
bytes.as_ref(),
|
||||
engine.config().deserialize_check_wasmtime_version,
|
||||
)?;
|
||||
module.into_module(engine)
|
||||
}
|
||||
|
||||
|
||||
@@ -329,7 +329,7 @@ impl<'a> SerializedModule<'a> {
|
||||
Ok(bytes)
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
|
||||
pub fn from_bytes(bytes: &[u8], check_version: bool) -> Result<Self> {
|
||||
if !bytes.starts_with(HEADER) {
|
||||
bail!("bytes are not a compatible serialized wasmtime module");
|
||||
}
|
||||
@@ -345,12 +345,14 @@ impl<'a> SerializedModule<'a> {
|
||||
bail!("serialized data is malformed");
|
||||
}
|
||||
|
||||
let version = std::str::from_utf8(&bytes[1..1 + version_len])?;
|
||||
if version != env!("CARGO_PKG_VERSION") {
|
||||
bail!(
|
||||
"Module was compiled with incompatible Wasmtime version '{}'",
|
||||
version
|
||||
);
|
||||
if check_version {
|
||||
let version = std::str::from_utf8(&bytes[1..1 + version_len])?;
|
||||
if version != env!("CARGO_PKG_VERSION") {
|
||||
bail!(
|
||||
"Module was compiled with incompatible Wasmtime version '{}'",
|
||||
version
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(bincode_options()
|
||||
|
||||
@@ -24,6 +24,13 @@ fn test_version_mismatch() -> Result<()> {
|
||||
.starts_with("Module was compiled with incompatible Wasmtime version")),
|
||||
}
|
||||
|
||||
// Test deserialize_check_wasmtime_version, which disables the logic which rejects the above.
|
||||
let mut config = Config::new();
|
||||
config.deserialize_check_wasmtime_version(false);
|
||||
let engine = Engine::new(&config).unwrap();
|
||||
unsafe { Module::deserialize(&engine, &buffer) }
|
||||
.expect("module with corrupt version should deserialize when check is disabled");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user