Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 32dcb6ba authored by Pawan Wagh's avatar Pawan Wagh Committed by Gerrit Code Review
Browse files

Merge "Using const array of functions in rust parcel fuzzer"

parents 6d4f8545 37b7fa88
Loading
Loading
Loading
Loading
+23 −26
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ extern crate libfuzzer_sys;

mod read_utils;

use crate::read_utils::get_read_funcs;
use crate::read_utils::READ_FUNCS;
use binder::binder_impl::{
    Binder, BorrowedParcel, IBinderInternal, Parcel, Stability, TransactionCode,
};
@@ -34,18 +34,18 @@ use binder_random_parcel_rs::create_random_parcel;
use libfuzzer_sys::arbitrary::Arbitrary;

#[derive(Arbitrary, Debug)]
enum ReadOperations {
enum ReadOperation {
    SetDataPosition { pos: i32 },
    GetDataSize,
    ReadParcelableHolder { is_vintf: bool },
    ReadBasicTypes { indexes: Vec<usize> },
    ReadBasicTypes { instructions: Vec<usize> },
}

#[derive(Arbitrary, Debug)]
enum Operations<'a> {
enum Operation<'a> {
    Transact { code: u32, flag: u32, data: &'a [u8] },
    Append { start: i32, len: i32, data1: &'a [u8], data2: &'a [u8], append_all: bool },
    Read { indexes: Vec<ReadOperations>, data: &'a [u8] },
    Read { read_operations: Vec<ReadOperation>, data: &'a [u8] },
}

/// Interface to fuzz transact with random parcel
@@ -102,13 +102,12 @@ fn do_append_fuzz(start: i32, len: i32, data1: &[u8], data2: &[u8], append_all:
    };
}

fn do_read_fuzz(read_operations: Vec<ReadOperations>, data: &[u8]) {
    let read_funcs = get_read_funcs();
fn do_read_fuzz(read_operations: Vec<ReadOperation>, data: &[u8]) {
    let parcel = create_random_parcel(data);

    for operation in read_operations {
        match operation {
            ReadOperations::SetDataPosition { pos } => {
            ReadOperation::SetDataPosition { pos } => {
                unsafe {
                    // Safety: Safe if pos is less than current size of the parcel.
                    // It relies on C++ code for bound checks
@@ -119,12 +118,12 @@ fn do_read_fuzz(read_operations: Vec<ReadOperations>, data: &[u8]) {
                }
            }

            ReadOperations::GetDataSize => {
            ReadOperation::GetDataSize => {
                let data_size = parcel.get_data_size();
                println!("data size from parcel: {:?}", data_size);
            }

            ReadOperations::ReadParcelableHolder { is_vintf } => {
            ReadOperation::ReadParcelableHolder { is_vintf } => {
                let stability = if is_vintf { Stability::Vintf } else { Stability::Local };
                let mut holder: ParcelableHolder = ParcelableHolder::new(stability);
                match holder.read_from_parcel(parcel.borrowed_ref()) {
@@ -135,30 +134,28 @@ fn do_read_fuzz(read_operations: Vec<ReadOperations>, data: &[u8]) {
                }
            }

            ReadOperations::ReadBasicTypes { indexes } => {
                for index in indexes.iter() {
                    let read_index = index % read_funcs.len();
                    read_funcs[read_index](parcel.borrowed_ref());
            ReadOperation::ReadBasicTypes { instructions } => {
                for instruction in instructions.iter() {
                    let read_index = instruction % READ_FUNCS.len();
                    READ_FUNCS[read_index](parcel.borrowed_ref());
                }
            }
        }
    }
}

fuzz_target!(|operations: Vec<Operations>| {
    for operation in operations {
fuzz_target!(|operation: Operation| {
    match operation {
            Operations::Transact { code, flag, data } => {
        Operation::Transact { code, flag, data } => {
            do_transact(code, data, flag);
        }

            Operations::Append { start, len, data1, data2, append_all } => {
        Operation::Append { start, len, data1, data2, append_all } => {
            do_append_fuzz(start, len, data1, data2, append_all);
        }

            Operations::Read { indexes, data } => {
                do_read_fuzz(indexes, data);
            }
        Operation::Read { read_operations, data } => {
            do_read_fuzz(read_operations, data);
        }
    }
});
+74 −78
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ use binderReadParcelIface::aidl::SingleDataParcelable::SingleDataParcelable;

macro_rules! read_parcel_interface {
    ($data_type:ty) => {
        |parcel| {
        |parcel: &BorrowedParcel<'_>| {
            let _res = parcel.read::<$data_type>();
        }
    };
@@ -57,52 +57,51 @@ impl binder::Parcelable for SomeParcelable {

binder::impl_deserialize_for_parcelable!(SomeParcelable);

pub fn get_read_funcs() -> Vec<Box<dyn Fn(&BorrowedParcel<'_>)>> {
    let read_funcs: Vec<Box<dyn Fn(&BorrowedParcel<'_>)>> = vec![
pub const READ_FUNCS: &[fn(&BorrowedParcel<'_>)] = &[
    //read basic types
        Box::new(read_parcel_interface!(bool)),
        Box::new(read_parcel_interface!(i8)),
        Box::new(read_parcel_interface!(i32)),
        Box::new(read_parcel_interface!(i64)),
        Box::new(read_parcel_interface!(f32)),
        Box::new(read_parcel_interface!(f64)),
        Box::new(read_parcel_interface!(u16)),
        Box::new(read_parcel_interface!(u32)),
        Box::new(read_parcel_interface!(u64)),
        Box::new(read_parcel_interface!(String)),
    read_parcel_interface!(bool),
    read_parcel_interface!(i8),
    read_parcel_interface!(i32),
    read_parcel_interface!(i64),
    read_parcel_interface!(f32),
    read_parcel_interface!(f64),
    read_parcel_interface!(u16),
    read_parcel_interface!(u32),
    read_parcel_interface!(u64),
    read_parcel_interface!(String),
    //read vec of basic types
        Box::new(read_parcel_interface!(Vec<i8>)),
        Box::new(read_parcel_interface!(Vec<i32>)),
        Box::new(read_parcel_interface!(Vec<i64>)),
        Box::new(read_parcel_interface!(Vec<f32>)),
        Box::new(read_parcel_interface!(Vec<f64>)),
        Box::new(read_parcel_interface!(Vec<u16>)),
        Box::new(read_parcel_interface!(Vec<u32>)),
        Box::new(read_parcel_interface!(Vec<u64>)),
        Box::new(read_parcel_interface!(Vec<String>)),
        Box::new(read_parcel_interface!(Option<Vec<i8>>)),
        Box::new(read_parcel_interface!(Option<Vec<i32>>)),
        Box::new(read_parcel_interface!(Option<Vec<i64>>)),
        Box::new(read_parcel_interface!(Option<Vec<f32>>)),
        Box::new(read_parcel_interface!(Option<Vec<f64>>)),
        Box::new(read_parcel_interface!(Option<Vec<u16>>)),
        Box::new(read_parcel_interface!(Option<Vec<u32>>)),
        Box::new(read_parcel_interface!(Option<Vec<u64>>)),
        Box::new(read_parcel_interface!(Option<Vec<String>>)),
        Box::new(read_parcel_interface!(ParcelFileDescriptor)),
        Box::new(read_parcel_interface!(Vec<Option<ParcelFileDescriptor>>)),
        Box::new(read_parcel_interface!(Option<Vec<ParcelFileDescriptor>>)),
        Box::new(read_parcel_interface!(Option<Vec<Option<ParcelFileDescriptor>>>)),
        Box::new(read_parcel_interface!(SpIBinder)),
        Box::new(read_parcel_interface!(Vec<Option<SpIBinder>>)),
        Box::new(read_parcel_interface!(Option<Vec<SpIBinder>>)),
        Box::new(read_parcel_interface!(Option<Vec<Option<SpIBinder>>>)),
        Box::new(read_parcel_interface!(SomeParcelable)),
        Box::new(read_parcel_interface!(Vec<Option<SomeParcelable>>)),
        Box::new(read_parcel_interface!(Option<Vec<SomeParcelable>>)),
        Box::new(read_parcel_interface!(Option<Vec<Option<SomeParcelable>>>)),
    read_parcel_interface!(Vec<i8>),
    read_parcel_interface!(Vec<i32>),
    read_parcel_interface!(Vec<i64>),
    read_parcel_interface!(Vec<f32>),
    read_parcel_interface!(Vec<f64>),
    read_parcel_interface!(Vec<u16>),
    read_parcel_interface!(Vec<u32>),
    read_parcel_interface!(Vec<u64>),
    read_parcel_interface!(Vec<String>),
    read_parcel_interface!(Option<Vec<i8>>),
    read_parcel_interface!(Option<Vec<i32>>),
    read_parcel_interface!(Option<Vec<i64>>),
    read_parcel_interface!(Option<Vec<f32>>),
    read_parcel_interface!(Option<Vec<f64>>),
    read_parcel_interface!(Option<Vec<u16>>),
    read_parcel_interface!(Option<Vec<u32>>),
    read_parcel_interface!(Option<Vec<u64>>),
    read_parcel_interface!(Option<Vec<String>>),
    read_parcel_interface!(ParcelFileDescriptor),
    read_parcel_interface!(Vec<Option<ParcelFileDescriptor>>),
    read_parcel_interface!(Option<Vec<ParcelFileDescriptor>>),
    read_parcel_interface!(Option<Vec<Option<ParcelFileDescriptor>>>),
    read_parcel_interface!(SpIBinder),
    read_parcel_interface!(Vec<Option<SpIBinder>>),
    read_parcel_interface!(Option<Vec<SpIBinder>>),
    read_parcel_interface!(Option<Vec<Option<SpIBinder>>>),
    read_parcel_interface!(SomeParcelable),
    read_parcel_interface!(Vec<Option<SomeParcelable>>),
    read_parcel_interface!(Option<Vec<SomeParcelable>>),
    read_parcel_interface!(Option<Vec<Option<SomeParcelable>>>),
    // Fuzz read_from_parcel for AIDL generated parcelables
        Box::new(|parcel| {
    |parcel| {
        let mut empty_parcelable: EmptyParcelable = EmptyParcelable::default();
        match empty_parcelable.read_from_parcel(parcel) {
            Ok(result) => result,
@@ -110,8 +109,8 @@ pub fn get_read_funcs() -> Vec<Box<dyn Fn(&BorrowedParcel<'_>)>> {
                println!("EmptyParcelable: error occurred while reading from a parcel: {:?}", e)
            }
        }
        }),
        Box::new(|parcel| {
    },
    |parcel| {
        let mut single_parcelable: SingleDataParcelable = SingleDataParcelable::default();
        match single_parcelable.read_from_parcel(parcel) {
            Ok(result) => result,
@@ -120,8 +119,8 @@ pub fn get_read_funcs() -> Vec<Box<dyn Fn(&BorrowedParcel<'_>)>> {
                e
            ),
        }
        }),
        Box::new(|parcel| {
    },
    |parcel| {
        let mut generic_parcelable: GenericDataParcelable = GenericDataParcelable::default();
        match generic_parcelable.read_from_parcel(parcel) {
            Ok(result) => result,
@@ -130,8 +129,5 @@ pub fn get_read_funcs() -> Vec<Box<dyn Fn(&BorrowedParcel<'_>)>> {
                e
            ),
        }
        }),
    },
];

    read_funcs
}