diff --git a/src/elf_parser/mod.rs b/src/elf_parser/mod.rs index 7cafa4e31..d992483f4 100644 --- a/src/elf_parser/mod.rs +++ b/src/elf_parser/mod.rs @@ -26,6 +26,9 @@ pub enum ElfParserError { /// Section or symbol name is not UTF8 or too long #[error("invalid string")] InvalidString, + /// Section or symbol name is too long + #[error("Section/symbol name size `{0}` longer than `{1}` bytes.")] + InvalidStringTooLong(String, usize), /// An index or memory range does exeed its boundaries #[error("value out of bounds")] OutOfBounds, @@ -392,11 +395,18 @@ impl<'a> Elf64<'a> { .elf_bytes .get(string_range) .ok_or(ElfParserError::OutOfBounds)?; + let string_bytes_unparsed = match String::from_utf8(unterminated_string_bytes.to_vec()) { + Ok(x) => x, + Err(_) => ElfParserError::InvalidString.to_string(), + }; unterminated_string_bytes .iter() .position(|byte| *byte == 0x00) .and_then(|string_length| unterminated_string_bytes.get(0..string_length)) - .ok_or(ElfParserError::InvalidString) + .ok_or(ElfParserError::InvalidStringTooLong( + string_bytes_unparsed, + maximum_length, + )) } /// Returns the string corresponding to the given `sh_name` diff --git a/src/elf_parser_glue.rs b/src/elf_parser_glue.rs index 687402cd2..e7502bd6c 100644 --- a/src/elf_parser_glue.rs +++ b/src/elf_parser_glue.rs @@ -527,6 +527,7 @@ impl From for ElfError { match err { ElfParserError::InvalidSectionHeader | ElfParserError::InvalidString + | ElfParserError::InvalidStringTooLong(_, _) | ElfParserError::InvalidSize | ElfParserError::Overlap | ElfParserError::SectionNotInOrder diff --git a/tests/elfs/long_section_name.so b/tests/elfs/long_section_name.so new file mode 100755 index 000000000..76f4f1417 Binary files /dev/null and b/tests/elfs/long_section_name.so differ diff --git a/tests/execution.rs b/tests/execution.rs index ddc30ab86..2a8a29e60 100644 --- a/tests/execution.rs +++ b/tests/execution.rs @@ -2208,6 +2208,26 @@ fn test_relative_call() { ); } +#[test] +#[should_panic( + expected = r#"called `Result::unwrap()` on an `Err` value: ElfError(FailedToParse("Section/symbol name size `.bss.__rust_no_a` longer than `16` bytes."))"# +)] +fn test_long_section_name() { + test_interpreter_and_jit_elf!( + "tests/elfs/long_section_name.so", + [1], + (), + TestContextObject::new(18), + ProgramResult::Err(EbpfError::ElfError( + solana_rbpf::elf_parser::ElfParserError::InvalidStringTooLong( + ".bss.__rust_no_a".to_string(), + 16 + ) + .into() + )), + ); +} + #[test] fn test_bpf_to_bpf_scratch_registers() { test_interpreter_and_jit_asm!(