From 029067c3c66aaec9e7d06bfac8023117a7fbb401 Mon Sep 17 00:00:00 2001 From: Andrew Haberlandt Date: Mon, 25 Jul 2022 10:42:20 -0400 Subject: [PATCH 1/2] Make EbpfError enum discriminant size explicit --- src/error.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/error.rs b/src/error.rs index bdd370f9..6163747c 100644 --- a/src/error.rs +++ b/src/error.rs @@ -24,6 +24,7 @@ pub trait UserDefinedError: 'static + std::error::Error {} /// Error definitions #[derive(Debug, thiserror::Error, PartialEq, Eq)] +#[repr(u64)] // discriminant size, used in emit_exception_kind in JIT pub enum EbpfError { /// User defined error #[error("{0}")] From b08a3687434c9a7615186b58f64cd70ee88dae0a Mon Sep 17 00:00:00 2001 From: Andrew Haberlandt Date: Wed, 27 Jul 2022 14:29:53 -0400 Subject: [PATCH 2/2] Add tests for enum discriminant size for enums used by the JIT It turns out that you can't try to ask for the size of std::mem::Discriminant and expect the right answer, so these tests mimic what the JIT is doing. --- tests/ubpf_execution.rs | 45 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/tests/ubpf_execution.rs b/tests/ubpf_execution.rs index 40d77f5c..8c8cbc36 100644 --- a/tests/ubpf_execution.rs +++ b/tests/ubpf_execution.rs @@ -4158,6 +4158,51 @@ fn test_tcp_sack_nomatch() { ); } +#[inline(never)] +fn copy_ebpf_error(err: &mut EbpfError) { + *err = EbpfError::DivideByZero(0); +} + +#[inline(never)] +fn copy_result(err: &mut Result) { + *err = Result::Err(EbpfError::DivideByZero(0)); +} + +#[test] +fn test_result_discriminant_size() { + unsafe { + // Create a Result> filled with 0xaa + let test: [u8; std::mem::size_of::()] = [0xaa; std::mem::size_of::()]; + let mut test_result = + std::mem::transmute::<[u8; std::mem::size_of::()], Result>(test); + // Overwrite the Result with another result + copy_result(&mut test_result); + + // Check that all 64-bits of the discriminant were changed + let err_kind = *(&test_result as *const _ as *const u64); + assert_eq!(err_kind, 1u64); + } +} + +#[test] +fn test_err_discriminant_size() { + unsafe { + // Create a EbpfError filled with 0xaa + let test: [u8; std::mem::size_of::>()] = + [0xaa; std::mem::size_of::>()]; + let mut test_err = std::mem::transmute::< + [u8; std::mem::size_of::>()], + EbpfError, + >(test); + // Overwrite the EbpfError with another error + copy_ebpf_error(&mut test_err); + + // Check that all 64-bits of the discriminant were changed + let err_kind = *(&test_err as *const _ as *const u64); + assert_eq!(err_kind, 7u64); + } +} + // Fuzzy #[cfg(all(not(windows), target_arch = "x86_64"))]