Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Tinywasm differential fuzzing oracle #1290

Open
Robbepop opened this issue Nov 4, 2024 · 2 comments
Open

Add Tinywasm differential fuzzing oracle #1290

Robbepop opened this issue Nov 4, 2024 · 2 comments

Comments

@Robbepop
Copy link
Member

Robbepop commented Nov 4, 2024

The Tinywasm Webassembly interpreter is interesting as a differential fuzzing oracle for Wasmi since it is a lightweight interpreter, supporting a similar Wasm feature set as Wasmi and is written in safe Rust entirely.

cc @explodingcamera Please feel free to share your thoughts if you support this. :)

Unfortunately it seems to be missing some important API, such as

  • Getting an exported Wasm global from a module instance.
  • Getting an exported Wasm table from a module instance.
  • Getting the whole byte slice of a memory instance.
  • Getting the whole table entries of a table instance.
  • etc..

As an example here is the oracle implementation for a legacy Wasmi version:
https://github.com/wasmi-labs/wasmi/blob/main/crates/fuzz/src/oracle/wasmi_stack.rs

In detail it is required to fully implement these traits:

In a PR attempt I was already able to implement the FuzzValue and FuzzError conversions:

impl From<WasmValue> for FuzzVal {
    fn from(value: WasmValue) -> Self {
        match value {
            WasmValue::I32(value) => Self::I32(value),
            WasmValue::I64(value) => Self::I64(value),
            WasmValue::F32(value) => Self::F32(value.into()),
            WasmValue::F64(value) => Self::F64(value.into()),
            WasmValue::RefNull(ty) => match ty {
                ValType::RefFunc => Self::FuncRef { is_null: true },
                ValType::RefExtern => Self::ExternRef { is_null: true },
                _ => unimplemented!(),
            },
            WasmValue::RefFunc(_value) => Self::FuncRef { is_null: false },
            WasmValue::RefExtern(_value) => Self::ExternRef { is_null: false },
            WasmValue::V128(_value) => unimplemented!(),
        }
    }
}

impl From<FuzzVal> for WasmValue {
    fn from(value: FuzzVal) -> Self {
        match value {
            FuzzVal::I32(value) => Self::I32(value),
            FuzzVal::I64(value) => Self::I64(value),
            FuzzVal::F32(value) => Self::F32(value.into()),
            FuzzVal::F64(value) => Self::F64(value.into()),
            FuzzVal::FuncRef { is_null } => {
                assert!(is_null);
                Self::RefNull(ValType::RefFunc)
            }
            FuzzVal::ExternRef { is_null } => {
                assert!(is_null);
                Self::RefNull(ValType::RefExtern)
            }
        }
    }
}

impl From<Error> for FuzzError {
    fn from(error: Error) -> Self {
        let Error::Trap(trap) = error else {
            return FuzzError::Other;
        };
        let trap_code = match trap {
            Trap::Unreachable => crate::TrapCode::UnreachableCodeReached,
            Trap::MemoryOutOfBounds { .. } => crate::TrapCode::MemoryOutOfBounds,
            Trap::TableOutOfBounds { .. } => crate::TrapCode::TableOutOfBounds,
            Trap::DivisionByZero => crate::TrapCode::IntegerDivisionByZero,
            Trap::InvalidConversionToInt => crate::TrapCode::BadConversionToInteger,
            Trap::IntegerOverflow => crate::TrapCode::IntegerOverflow,
            Trap::CallStackOverflow => crate::TrapCode::StackOverflow,
            Trap::UndefinedElement { .. } => {
                crate::TrapCode::BadSignature // not sure if this error fits
            }
            Trap::UninitializedElement { .. } => {
                crate::TrapCode::BadSignature // not sure if this error fits
            }
            Trap::IndirectCallTypeMismatch { .. } => crate::TrapCode::IndirectCallToNull,
        };
        FuzzError::Trap(trap_code)
    }
}
@explodingcamera
Copy link

Hi, sounds interesting! I'll be sure to add those APIs to my todo list for the next release, the public API has been a bit neglected.

@Robbepop
Copy link
Member Author

Robbepop commented Nov 7, 2024

Hi, sounds interesting! I'll be sure to add those APIs to my todo list for the next release, the public API has been a bit neglected.

Great! Sounds good. I'd be happy to be updated here once the new update lands. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants