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

Commit 51274715 authored by Pawan Wagh's avatar Pawan Wagh Committed by Automerger Merge Worker
Browse files

Merge "Using const array of functions in rust parcel fuzzer" am: 32dcb6ba am: 1b960d50

parents d0b80151 1b960d50
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
}