Skip to content

Commit 450321c

Browse files
Fuzzing: Update FuzzTranslator to instantiate modules explicitly (#152)
1 parent 65ed01b commit 450321c

File tree

6 files changed

+59
-39
lines changed

6 files changed

+59
-39
lines changed

FuzzTesting/Package.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ let package = Package(
3131
],
3232
targets: [
3333
.target(name: "FuzzTranslator", dependencies: [
34+
"WasmKitFuzzing",
3435
.product(name: "WasmKit", package: "WasmKit")
3536
]),
3637
.target(name: "FuzzExecute", dependencies: [
@@ -42,5 +43,8 @@ let package = Package(
4243
"WasmCAPI",
4344
]),
4445
.target(name: "WasmCAPI"),
46+
.target(name: "WasmKitFuzzing", dependencies: [
47+
.product(name: "WasmKit", package: "WasmKit"),
48+
])
4549
]
4650
)

FuzzTesting/Sources/FuzzTranslator/FuzzTranslator.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import WasmKit
2+
import WasmKitFuzzing
23

34
@_cdecl("LLVMFuzzerTestOneInput")
45
public func FuzzCheck(_ start: UnsafePointer<UInt8>, _ count: Int) -> CInt {
56
let bytes = Array(UnsafeBufferPointer(start: start, count: count))
67
do {
7-
var module = try WasmKit.parseWasm(bytes: bytes)
8-
try module.materializeAll()
8+
try fuzzInstantiation(bytes: bytes)
99
} catch {
1010
// Ignore errors
1111
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// This module defines utilities for fuzzing WasmKit.
2+
3+
import WasmKit
4+
5+
/// Check if a Wasm module can be instantiated without crashing.
6+
///
7+
/// - Parameter bytes: The bytes of the Wasm module.
8+
public func fuzzInstantiation(bytes: [UInt8]) throws {
9+
let module = try WasmKit.parseWasm(bytes: bytes)
10+
let engine = Engine(configuration: EngineConfiguration(compilationMode: .eager))
11+
let store = Store(engine: engine)
12+
13+
// Prepare dummy imports
14+
var imports = Imports()
15+
for importEntry in module.imports {
16+
let value: ExternalValueConvertible
17+
switch importEntry.descriptor {
18+
case .function(let typeIndex):
19+
guard typeIndex < module.types.count else {
20+
// Skip if import type index is out of bounds
21+
return
22+
}
23+
let type = module.types[Int(typeIndex)]
24+
value = Function(store: store, type: type) { _, _ in
25+
// Provide "start function" with empty results
26+
if type.results.isEmpty { return [] }
27+
fatalError("Unexpected function call")
28+
}
29+
case .global(let globalType):
30+
value = try Global(store: store, type: globalType, value: .i32(0))
31+
case .memory(let memoryType):
32+
value = try Memory(store: store, type: memoryType)
33+
case .table(let tableType):
34+
value = try Table(store: store, type: tableType)
35+
}
36+
imports.define(module: importEntry.module, name: importEntry.name, value.externalValue)
37+
}
38+
39+
// Instantiate the module
40+
_ = try module.instantiate(store: store, imports: imports)
41+
}

Package.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,14 @@ let package = Package(
4848
exclude: ["CMakeLists.txt"]
4949
),
5050
.target(name: "_CWasmKit"),
51+
.target(
52+
name: "WasmKitFuzzing",
53+
dependencies: ["WasmKit"],
54+
path: "FuzzTesting/Sources/WasmKitFuzzing"
55+
),
5156
.testTarget(
5257
name: "WasmKitTests",
53-
dependencies: ["WasmKit", "WAT"],
58+
dependencies: ["WasmKit", "WAT", "WasmKitFuzzing"],
5459
exclude: ["ExtraSuite"]
5560
),
5661

Sources/WasmKit/Module.swift

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -227,13 +227,8 @@ public struct Module {
227227
}
228228

229229
/// Materialize lazily-computed elements in this module
230-
public mutating func materializeAll() throws {
231-
let allocator = ISeqAllocator()
232-
let funcTypeInterner = Interner<FunctionType>()
233-
for function in functions {
234-
_ = try function.compile(module: self, funcTypeInterner: funcTypeInterner, allocator: allocator)
235-
}
236-
}
230+
@available(*, deprecated, message: "Module materialization is no longer supported. Instantiate the module explicitly instead.")
231+
public mutating func materializeAll() throws {}
237232
}
238233

239234
extension Module {
@@ -275,8 +270,4 @@ typealias LabelIndex = UInt32
275270
struct GuestFunction {
276271
let type: FunctionType
277272
let code: Code
278-
279-
func compile(module: Module, funcTypeInterner: Interner<FunctionType>, allocator: ISeqAllocator) throws -> InstructionSequence {
280-
throw TranslationError("Compile without instantiation is no longer supported")
281-
}
282273
}

Tests/WasmKitTests/FuzzTranslatorRegressionTests.swift

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import WasmKit
2+
import WasmKitFuzzing
23
import XCTest
34

45
final class FuzzTranslatorRegressionTests: XCTestCase {
5-
func testRunAll() async throws {
6+
func testRunAll() throws {
67
let sourceRoot = URL(fileURLWithPath: #filePath)
78
.deletingLastPathComponent().deletingLastPathComponent().deletingLastPathComponent()
89
let failCasesDir =
@@ -12,33 +13,11 @@ final class FuzzTranslatorRegressionTests: XCTestCase {
1213
for file in try FileManager.default.contentsOfDirectory(atPath: failCasesDir.path) {
1314
let path = failCasesDir.appendingPathComponent(file).path
1415
print("Fuzz regression test: \(path.dropFirst(sourceRoot.path.count + 1))")
15-
1616
let data = try Data(contentsOf: URL(fileURLWithPath: path))
1717
do {
18-
let module = try WasmKit.parseWasm(bytes: Array(data))
19-
let engine = Engine(configuration: EngineConfiguration(compilationMode: .eager))
20-
let store = Store(engine: engine)
21-
var imports = Imports()
22-
for importEntry in module.imports {
23-
let value: ExternalValueConvertible
24-
switch importEntry.descriptor {
25-
case .function(let typeIndex):
26-
let type = module.types[Int(typeIndex)]
27-
value = Function(store: store, type: type) { _, _ in
28-
fatalError("unreachable")
29-
}
30-
case .global(let globalType):
31-
value = try Global(store: store, type: globalType, value: .i32(0))
32-
case .memory(let memoryType):
33-
value = try Memory(store: store, type: memoryType)
34-
case .table(let tableType):
35-
value = try Table(store: store, type: tableType)
36-
}
37-
imports.define(module: importEntry.module, name: importEntry.name, value.externalValue)
38-
}
39-
_ = try module.instantiate(store: store, imports: imports)
18+
try WasmKitFuzzing.fuzzInstantiation(bytes: Array(data))
4019
} catch {
41-
// Explicit errors are ok
20+
// Skip exceptions without crash
4221
}
4322
}
4423
}

0 commit comments

Comments
 (0)