Skip to content

Commit 2132614

Browse files
committed
fix: only keep RELRO_PADDING section when relro is enabled
1 parent 6afbc31 commit 2132614

3 files changed

Lines changed: 100 additions & 1 deletion

File tree

libwild/src/elf.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,6 @@ impl platform::Platform for Elf {
417417
output_section_id::PROGRAM_HEADERS,
418418
output_section_id::SECTION_HEADERS,
419419
output_section_id::SHSTRTAB,
420-
output_section_id::RELRO_PADDING,
421420
];
422421

423422
for section_id in FORCE_KEEP_SECTIONS {

wild/tests/integration_tests.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@
5757
//! ExpectLoadAlignment:{alignment} Checks that the first PT_LOAD segment in the output binary has
5858
//! the specified alignment.
5959
//!
60+
//! ExpectProgramHeader:{type} Checks that the output binary contains a program header of the
61+
//! specified type.
62+
//!
63+
//! NoProgramHeader:{type} Checks that the output binary contains no program headers of the
64+
//! specified type.
65+
//!
6066
//! DoesNotContain:{string} Checks that the output binary doesn't contain the specified string.
6167
//!
6268
//! Contains:{string} Checks that the output binary does contain the specified string.
@@ -814,6 +820,23 @@ enum DriverMode {
814820
SaveDirResponse,
815821
}
816822

823+
#[derive(Clone, Copy, Debug, Display, PartialEq, Eq, EnumString)]
824+
#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
825+
#[repr(u32)]
826+
enum ProgramHeaderType {
827+
Dynamic = object::elf::PT_DYNAMIC,
828+
Interp = object::elf::PT_INTERP,
829+
GnuEhFrame = object::elf::PT_GNU_EH_FRAME,
830+
GnuProperty = object::elf::PT_GNU_PROPERTY,
831+
GnuRelro = object::elf::PT_GNU_RELRO,
832+
GnuStack = object::elf::PT_GNU_STACK,
833+
Load = object::elf::PT_LOAD,
834+
Note = object::elf::PT_NOTE,
835+
Null = object::elf::PT_NULL,
836+
Phdr = object::elf::PT_PHDR,
837+
Tls = object::elf::PT_TLS,
838+
}
839+
817840
#[derive(Debug, Clone)]
818841
struct ErrorMatcher {
819842
regex: regex::Regex,
@@ -1140,6 +1163,8 @@ struct Assertions {
11401163
expected_section_bytes: Vec<ExpectedSectionBytes>,
11411164
output_file_matches: Vec<OutputFileMatch>,
11421165
max_thunks: u64,
1166+
expected_program_headers: Vec<ProgramHeaderType>,
1167+
absent_program_headers: Vec<ProgramHeaderType>,
11431168
}
11441169

11451170
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -1498,6 +1523,18 @@ fn process_directive(
14981523
};
14991524
config.assertions.expected_load_alignment = Some(alignment);
15001525
}
1526+
"ExpectProgramHeader" => {
1527+
let header_type: ProgramHeaderType = arg
1528+
.parse()
1529+
.with_context(|| format!("Invalid program header type `{arg}`"))?;
1530+
config.assertions.expected_program_headers.push(header_type);
1531+
}
1532+
"NoProgramHeader" => {
1533+
let header_type: ProgramHeaderType = arg
1534+
.parse()
1535+
.with_context(|| format!("Invalid program header type `{arg}`"))?;
1536+
config.assertions.absent_program_headers.push(header_type);
1537+
}
15011538
"Mode" => {
15021539
let mode: Mode = arg
15031540
.parse()
@@ -3430,6 +3467,7 @@ impl Assertions {
34303467
self.verify_dynamic_entries(&elf_obj)?;
34313468
self.verify_symbols_absent(&self.no_sym, elf_obj.dynamic_symbols(), "dynsym")?;
34323469
self.verify_symbols_absent(&self.no_dynsym, elf_obj.dynamic_symbols(), "dynsym")?;
3470+
self.verify_program_headers(&elf_obj)?;
34333471
}
34343472
object::File::MachO64(_) => {
34353473
if !self.expected_comments.is_empty() {
@@ -3447,6 +3485,12 @@ impl Assertions {
34473485
if !self.absent_dynamic_entries.is_empty() {
34483486
bail!("NoDynamic is not supported for MachO",);
34493487
}
3488+
if !self.expected_program_headers.is_empty() {
3489+
bail!("ExpectProgramHeader is not supported for MachO",);
3490+
}
3491+
if !self.absent_program_headers.is_empty() {
3492+
bail!("NoProgramHeader is not supported for MachO");
3493+
}
34503494
}
34513495
_ => bail!("Unsupported object file format"),
34523496
}
@@ -3676,6 +3720,36 @@ impl Assertions {
36763720
Ok(())
36773721
}
36783722

3723+
fn verify_program_headers<'data>(
3724+
&self,
3725+
obj: &object::read::elf::ElfFile64<'data, object::Endianness>,
3726+
) -> Result {
3727+
if self.expected_program_headers.is_empty() && self.absent_program_headers.is_empty() {
3728+
return Ok(());
3729+
}
3730+
3731+
let endian = obj.endian();
3732+
let mut header_types = HashSet::new();
3733+
3734+
for header in obj.elf_program_headers() {
3735+
header_types.insert(header.p_type(endian));
3736+
}
3737+
3738+
for header in &self.expected_program_headers {
3739+
if !header_types.contains(&(*header as u32)) {
3740+
bail!("Expected program header `{header}' not found.");
3741+
}
3742+
}
3743+
3744+
for header in &self.absent_program_headers {
3745+
if header_types.contains(&(*header as u32)) {
3746+
bail!("Program header `{header}' should be absent but was found.");
3747+
}
3748+
}
3749+
3750+
Ok(())
3751+
}
3752+
36793753
/// Returns whether we have assertions configured that require metrics to be enabled. Even if
36803754
/// this returns false, if diffing is enabled, we'll collect metrics and check them.
36813755
fn requires_metrics(&self) -> bool {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//#AbstractConfig:default
2+
// Create a .got.plt section to force ld to include a PT_GNU_RELRO program
3+
// header
4+
//#Shared:runtime.c
5+
//#Mode:dynamic
6+
//#DiffIgnore:section.got
7+
//#DiffIgnore:.dynamic.DT_NEEDED
8+
//#DiffIgnore:.dynamic.DT_FLAGS_1.NOW
9+
//#DiffIgnore:.dynamic.DT_RELA
10+
//#DiffIgnore:.dynamic.DT_RELAENT
11+
12+
//#Config:enabled:default
13+
//#LinkArgs:-z relro
14+
//#ExpectProgramHeader:GNU_RELRO
15+
16+
//#Config:disabled:default
17+
//#LinkArgs:-z norelro
18+
//#NoProgramHeader:GNU_RELRO
19+
//#DoesNotContain:relro_padding
20+
21+
#include "../common/runtime.h"
22+
23+
void _start() {
24+
runtime_init();
25+
exit_syscall(42);
26+
}

0 commit comments

Comments
 (0)