File: WasmKitFuzzing.swift

package info (click to toggle)
swiftlang 6.2.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,856,264 kB
  • sloc: cpp: 9,995,718; ansic: 2,234,019; asm: 1,092,167; python: 313,940; objc: 82,726; f90: 80,126; lisp: 38,373; pascal: 25,580; sh: 20,378; ml: 5,058; perl: 4,751; makefile: 4,725; awk: 3,535; javascript: 3,018; xml: 918; fortran: 664; cs: 573; ruby: 396
file content (54 lines) | stat: -rw-r--r-- 2,069 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// This module defines utilities for fuzzing WasmKit.

@_spi(Fuzzing) import WasmKit

/// A resource limiter that restricts allocations to fuzzer limits.
public struct FuzzerResourceLimiter: ResourceLimiter {
    public init() {}

    public func limitMemoryGrowth(to desired: Int) throws -> Bool {
        return desired < 1024 * 1024 * 1024
    }
    public func limitTableGrowth(to desired: Int) throws -> Bool {
        return desired < 1024 * 1024
    }
}

/// Check if a Wasm module can be instantiated without crashing.
///
/// - Parameter bytes: The bytes of the Wasm module.
public func fuzzInstantiation(bytes: [UInt8]) throws {
    let module = try WasmKit.parseWasm(bytes: bytes)
    let engine = Engine(configuration: EngineConfiguration(compilationMode: .eager))
    let store = Store(engine: engine)
    store.resourceLimiter = FuzzerResourceLimiter()

    // Prepare dummy imports
    var imports = Imports()
    for importEntry in module.imports {
        let value: ExternalValueConvertible
        switch importEntry.descriptor {
        case .function(let typeIndex):
            guard typeIndex < module.types.count else {
                // Skip if import type index is out of bounds
                return
            }
            let type = module.types[Int(typeIndex)]
            value = Function(store: store, type: type) { _, _ in
                // Provide "start function" with empty results
                if type.results.isEmpty { return [] }
                fatalError("Unexpected function call")
            }
        case .global(let globalType):
            value = try Global(store: store, type: globalType, value: .i32(0))
        case .memory(let memoryType):
            value = try Memory(store: store, type: memoryType)
        case .table(let tableType):
            value = try Table(store: store, type: tableType)
        }
        imports.define(module: importEntry.module, name: importEntry.name, value.externalValue)
    }

    // Instantiate the module
    _ = try module.instantiate(store: store, imports: imports)
}