Skip to content
This repository has been archived by the owner on Mar 26, 2023. It is now read-only.

Undefined behavior when using binding to QPL in the runner #9

Open
clauverjat opened this issue Jan 30, 2023 · 0 comments
Open

Undefined behavior when using binding to QPL in the runner #9

clauverjat opened this issue Jan 30, 2023 · 0 comments

Comments

@clauverjat
Copy link
Contributor

clauverjat commented Jan 30, 2023

The issue manifest with the following code : https://github.com/mithril-security/blindai-preview/blob/main/runner/remote_attestation_sgx/src/quote_verification_collateral.rs#L246

    // Retrieving verification collateral using QPL
    let mut p_quote_collateral: *mut sgx_ql_qve_collateral_t = ptr::null_mut();
    let qv_ret = unsafe {
        sgx_ql_get_quote_verification_collateral(
            fmspc.as_ptr(),
            fmspc.len() as u16,
            ca_from_quote.as_ptr(),
            &mut p_quote_collateral as *mut *mut sgx_ql_qve_collateral_t,
        )
    };

    ensure!(
        qv_ret == Quote3Error::Success,
        "sgx_ql_get_quote_verification_collateral failed!"
    );

The code kinda of work, but it is still broken. It manifested when trying to debug a failure from the call to sgx_ql_get_quote_verification_collateral. We added that before the ensure! to print the error code from the QPL.

println!("sgx_ql_get_quote_verification_collateral returned {:?}", qv_ret);

Quite surprisingly in release mode we got sgx_ql_get_quote_verification_collateral returned Quote3Error::Success despite the fact that qv_ret == Quote3Error::Success was false... The issue disappeared when compiling in debug mode, with the debug build simply printing a a status different from Quote3Error::Success, (yet it was still the wrong status).
As one can imagine the surprising behavior is actually due to an UB which is due to how we declared the FFI interface between the QPL and our rust code.

extern "C" {
    pub fn sgx_ql_get_quote_verification_collateral(
        fmspc: *const u8,
        fmspc_size: u16,
        pck_ra: *const c_char,
        pp_quote_collateral: *mut *mut sgx_ql_qve_collateral_t,
    ) -> Quote3Error;
    pub fn sgx_ql_free_quote_verification_collateral(
        p_quote_collateral: *const sgx_ql_qve_collateral_t,
    ) -> Quote3Error;
}

The return of the function is declared as a Quote3Error which is a Rust enum. A Rust enum is assumed to only take one of the declared values (it cannot host any int8 like what might be done in C). In our case the strange behavior was due to the fact that the QPL returned an enum value that was not expected by the Rust enum. See https://mdaverde.com/posts/rust-bindgen-enum/ for more information.

What should we do to fix it ?
The best course of action would be to replace our custom FFI interface declaration with an FFI declaration generated automatically via rust-bindgen. This would avoid this kind of mistake (and also would ensure that the function signature match...). We should also look if there are already rust crates on crates.io which have already done that.

Security impact : No (outside of enclave).
Priority : Low (only impacts the error path)

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

No branches or pull requests

1 participant