Skip to content

Commit f5a9490

Browse files
authored
[34.0.0] Fix globals/tables holding their registered types (#11104)
* Fix globals/tables holding their registered types This commit fixes an issue where host-created tables and globals with concrete reference types previously did not keep their associated type registrations alive for the duration of the table or global itself. This could lead to runtime panics when reflecting on their type and additionally lead to some type confusion about the global/table itself. As described in #11102 this is not a security issue, just a bug that needs fixing. Closes #11102 * Fix compile
1 parent 597c0c8 commit f5a9490

File tree

8 files changed

+123
-42
lines changed

8 files changed

+123
-42
lines changed

crates/wasmtime/src/runtime/trampoline.rs

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,36 +12,10 @@ pub(crate) use memory::MemoryCreatorProxy;
1212
use self::memory::create_memory;
1313
use self::table::create_table;
1414
use crate::prelude::*;
15-
use crate::runtime::vm::{
16-
Imports, ModuleRuntimeInfo, OnDemandInstanceAllocator, SharedMemory, VMFunctionImport,
17-
};
18-
use crate::store::{AllocateInstanceKind, InstanceId, StoreOpaque};
15+
use crate::runtime::vm::SharedMemory;
16+
use crate::store::StoreOpaque;
1917
use crate::{MemoryType, TableType};
20-
use alloc::sync::Arc;
21-
use wasmtime_environ::{MemoryIndex, Module, TableIndex, VMSharedTypeIndex};
22-
23-
fn create_handle(
24-
module: Module,
25-
store: &mut StoreOpaque,
26-
func_imports: &[VMFunctionImport],
27-
one_signature: Option<VMSharedTypeIndex>,
28-
) -> Result<InstanceId> {
29-
let mut imports = Imports::default();
30-
imports.functions = func_imports;
31-
32-
unsafe {
33-
let allocator =
34-
OnDemandInstanceAllocator::new(store.engine().config().mem_creator.clone(), 0, false);
35-
let module = Arc::new(module);
36-
store.allocate_instance(
37-
AllocateInstanceKind::Dummy {
38-
allocator: &allocator,
39-
},
40-
&ModuleRuntimeInfo::bare_maybe_imported_func(module, one_signature),
41-
imports,
42-
)
43-
}
44-
}
18+
use wasmtime_environ::{MemoryIndex, TableIndex};
4519

4620
pub fn generate_memory_export(
4721
store: &mut StoreOpaque,

crates/wasmtime/src/runtime/trampoline/global.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::runtime::vm::{ExportGlobalKind, StoreBox, VMGlobalDefinition};
22
use crate::store::{AutoAssertNoGc, StoreOpaque};
3+
use crate::type_registry::RegisteredType;
34
use crate::{GlobalType, Mutability, Result, RootedGcRefImpl, Val};
45
use core::ptr::{self, NonNull};
56
use wasmtime_environ::{DefinedGlobalIndex, EntityRef, Global};
@@ -8,6 +9,8 @@ use wasmtime_environ::{DefinedGlobalIndex, EntityRef, Global};
89
pub struct VMHostGlobalContext {
910
pub(crate) ty: Global,
1011
pub(crate) global: VMGlobalDefinition,
12+
13+
_registered_type: Option<RegisteredType>,
1114
}
1215

1316
pub fn generate_global_export(
@@ -25,6 +28,7 @@ pub fn generate_global_export(
2528
let ctx = StoreBox::new(VMHostGlobalContext {
2629
ty: global,
2730
global: VMGlobalDefinition::new(),
31+
_registered_type: ty.into_registered_type(),
2832
});
2933

3034
let mut store = AutoAssertNoGc::new(store);

crates/wasmtime/src/runtime/trampoline/memory.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub fn create_memory(
5656
AllocateInstanceKind::Dummy {
5757
allocator: &allocator,
5858
},
59-
&ModuleRuntimeInfo::bare_maybe_imported_func(Arc::new(module), None),
59+
&ModuleRuntimeInfo::bare(Arc::new(module)),
6060
Default::default(),
6161
)
6262
}

crates/wasmtime/src/runtime/trampoline/table.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use crate::TableType;
22
use crate::prelude::*;
3-
use crate::store::{InstanceId, StoreOpaque};
4-
use crate::trampoline::create_handle;
3+
use crate::runtime::vm::{Imports, ModuleRuntimeInfo, OnDemandInstanceAllocator};
4+
use crate::store::{AllocateInstanceKind, InstanceId, StoreOpaque};
5+
use alloc::sync::Arc;
56
use wasmtime_environ::{EntityIndex, Module, TypeTrace};
67

78
pub fn create_table(store: &mut StoreOpaque, table: &TableType) -> Result<InstanceId> {
@@ -22,5 +23,21 @@ pub fn create_table(store: &mut StoreOpaque, table: &TableType) -> Result<Instan
2223
.exports
2324
.insert(String::new(), EntityIndex::Table(table_id));
2425

25-
create_handle(module, store, &[], None)
26+
let imports = Imports::default();
27+
28+
unsafe {
29+
let allocator =
30+
OnDemandInstanceAllocator::new(store.engine().config().mem_creator.clone(), 0, false);
31+
let module = Arc::new(module);
32+
store.allocate_instance(
33+
AllocateInstanceKind::Dummy {
34+
allocator: &allocator,
35+
},
36+
&ModuleRuntimeInfo::bare_with_registered_type(
37+
module,
38+
table.element().clone().into_registered_type(),
39+
),
40+
imports,
41+
)
42+
}
2643
}

crates/wasmtime/src/runtime/types.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,13 @@ impl ValType {
362362
}
363363
}
364364
}
365+
366+
pub(crate) fn into_registered_type(self) -> Option<RegisteredType> {
367+
match self {
368+
ValType::Ref(ty) => ty.into_registered_type(),
369+
_ => None,
370+
}
371+
}
365372
}
366373

367374
/// Opaque references to data in the Wasm heap or to host data.
@@ -536,6 +543,10 @@ impl RefType {
536543
pub(crate) fn is_vmgcref_type_and_points_to_object(&self) -> bool {
537544
self.heap_type().is_vmgcref_type_and_points_to_object()
538545
}
546+
547+
pub(crate) fn into_registered_type(self) -> Option<RegisteredType> {
548+
self.heap_type.into_registered_type()
549+
}
539550
}
540551

541552
/// The heap types that can Wasm can have references to.
@@ -1160,6 +1171,18 @@ impl HeapType {
11601171
HeapType::I31 | HeapType::NoExtern | HeapType::NoFunc | HeapType::None
11611172
)
11621173
}
1174+
1175+
pub(crate) fn into_registered_type(self) -> Option<RegisteredType> {
1176+
use HeapType::*;
1177+
match self {
1178+
ConcreteFunc(ty) => Some(ty.registered_type),
1179+
ConcreteArray(ty) => Some(ty.registered_type),
1180+
ConcreteStruct(ty) => Some(ty.registered_type),
1181+
Extern | NoExtern | Func | NoFunc | Any | Eq | I31 | Array | Struct | None => {
1182+
Option::None
1183+
}
1184+
}
1185+
}
11631186
}
11641187

11651188
// External Types
@@ -2502,6 +2525,10 @@ impl GlobalType {
25022525
.ok_or_else(|| anyhow!("global type has no default value"))?;
25032526
RuntimeGlobal::new(store, self.clone(), val)
25042527
}
2528+
2529+
pub(crate) fn into_registered_type(self) -> Option<RegisteredType> {
2530+
self.content.into_registered_type()
2531+
}
25052532
}
25062533

25072534
// Tag Types

crates/wasmtime/src/runtime/vm.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub(crate) struct f64x2(crate::uninhabited::Uninhabited);
3535

3636
use crate::prelude::*;
3737
use crate::store::StoreOpaque;
38+
use crate::type_registry::RegisteredType;
3839
use alloc::sync::Arc;
3940
use core::fmt;
4041
use core::ops::Deref;
@@ -313,23 +314,23 @@ pub enum ModuleRuntimeInfo {
313314
#[derive(Clone)]
314315
pub struct BareModuleInfo {
315316
module: Arc<wasmtime_environ::Module>,
316-
one_signature: Option<VMSharedTypeIndex>,
317317
offsets: VMOffsets<HostPtr>,
318+
_registered_type: Option<RegisteredType>,
318319
}
319320

320321
impl ModuleRuntimeInfo {
321322
pub(crate) fn bare(module: Arc<wasmtime_environ::Module>) -> Self {
322-
ModuleRuntimeInfo::bare_maybe_imported_func(module, None)
323+
ModuleRuntimeInfo::bare_with_registered_type(module, None)
323324
}
324325

325-
pub(crate) fn bare_maybe_imported_func(
326+
pub(crate) fn bare_with_registered_type(
326327
module: Arc<wasmtime_environ::Module>,
327-
one_signature: Option<VMSharedTypeIndex>,
328+
registered_type: Option<RegisteredType>,
328329
) -> Self {
329330
ModuleRuntimeInfo::Bare(Box::new(BareModuleInfo {
330331
offsets: VMOffsets::new(HostPtr, &module),
331332
module,
332-
one_signature,
333+
_registered_type: registered_type,
333334
}))
334335
}
335336

@@ -431,10 +432,7 @@ impl ModuleRuntimeInfo {
431432
.as_module_map()
432433
.values()
433434
.as_slice(),
434-
ModuleRuntimeInfo::Bare(b) => match &b.one_signature {
435-
Some(s) => core::slice::from_ref(s),
436-
None => &[],
437-
},
435+
ModuleRuntimeInfo::Bare(_) => &[],
438436
}
439437
}
440438

tests/all/globals.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,3 +432,35 @@ fn instantiate_global_with_subtype() -> Result<()> {
432432

433433
Ok(())
434434
}
435+
436+
#[test]
437+
fn host_globals_keep_type_registration() -> Result<()> {
438+
let engine = Engine::default();
439+
let mut store = Store::new(&engine, ());
440+
441+
let ty = FuncType::new(&engine, [], []);
442+
443+
let g = Global::new(
444+
&mut store,
445+
GlobalType::new(
446+
RefType::new(true, HeapType::ConcreteFunc(ty)).into(),
447+
Mutability::Const,
448+
),
449+
Val::FuncRef(None),
450+
)?;
451+
452+
{
453+
let _ty2 = FuncType::new(&engine, [ValType::I32], [ValType::I32]);
454+
let ty = g.ty(&store);
455+
let fty = ty.content().unwrap_ref().heap_type().unwrap_concrete_func();
456+
assert!(fty.params().len() == 0);
457+
assert!(fty.results().len() == 0);
458+
}
459+
460+
let ty = g.ty(&store);
461+
let fty = ty.content().unwrap_ref().heap_type().unwrap_concrete_func();
462+
assert!(fty.params().len() == 0);
463+
assert!(fty.results().len() == 0);
464+
465+
Ok(())
466+
}

tests/all/table.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,3 +337,32 @@ fn i31ref_table_copy() -> Result<()> {
337337

338338
Ok(())
339339
}
340+
341+
#[test]
342+
fn host_table_keep_type_registration() -> Result<()> {
343+
let engine = Engine::default();
344+
let mut store = Store::new(&engine, ());
345+
346+
let ty = FuncType::new(&engine, [], []);
347+
348+
let t = Table::new(
349+
&mut store,
350+
TableType::new(RefType::new(true, HeapType::ConcreteFunc(ty)), 1, None),
351+
Ref::Func(None),
352+
)?;
353+
354+
{
355+
let _ty2 = FuncType::new(&engine, [ValType::I32], [ValType::I32]);
356+
let ty = t.ty(&store);
357+
let fty = ty.element().heap_type().unwrap_concrete_func();
358+
assert!(fty.params().len() == 0);
359+
assert!(fty.results().len() == 0);
360+
}
361+
362+
let ty = t.ty(&store);
363+
let fty = ty.element().heap_type().unwrap_concrete_func();
364+
assert!(fty.params().len() == 0);
365+
assert!(fty.results().len() == 0);
366+
367+
Ok(())
368+
}

0 commit comments

Comments
 (0)