From ed2633bf954dbffb3ab953f9d6b2d7ddb537aa47 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Sun, 26 Nov 2023 11:46:12 -0800 Subject: [PATCH] Honor .p_align <= 64K; else assume 4K is also available https://github.com/upx/upx/issues/737 modified: p_lx_elf.cpp --- src/p_lx_elf.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index c6be909f..95360002 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -3967,7 +3967,15 @@ void PackLinuxElf32::pack1(OutputFile * /*fo*/, Filter &ft) ++lg2_page; } } - if (PT_GNU_RELRO32 == type) { + if (PT_GNU_RELRO32 == type + && 16 < lg2_page) { + // x86* allows 4K, 2M, 1G + // arm32 and arm64 both allow 4K, 16K, 64K; Apple Silicon uses 16K + // Oracle 5.4.17-2136.314.6.2.el8uek.aarch64 demands 64K + // PowerPC and PowerPC64 has 4K, 64K, 1M (?), 16M (?) + // MIPS allows any power of 2 from 4K through 64K + + // If 64K < .p_align then we assume that 4K is also accepted. // .p_align can be like 2M, which is a huge over-estimate. // RELRO ends on a page boundary: usually close to actual page_size unsigned offset = get_te32(&phdr->p_offset); @@ -3978,7 +3986,7 @@ void PackLinuxElf32::pack1(OutputFile * /*fo*/, Filter &ft) ++b; } lg2_page = umin(lg2_page, -1+ b); - } + } } if (PT_GNU_STACK32 == type) { gnu_stack = phdr; @@ -4849,7 +4857,15 @@ void PackLinuxElf64::pack1(OutputFile * /*fo*/, Filter &ft) ++lg2_page; } } - if (PT_GNU_RELRO64 == type) { + if (PT_GNU_RELRO64 == type + && 16 < lg2_page) { + // x86* allows 4K, 2M, 1G + // arm32 and arm64 both allow 4K, 16K, 64K; Apple Silicon uses 16K + // Oracle 5.4.17-2136.314.6.2.el8uek.aarch64 demands 64K + // PowerPC and PowerPC64 has 4K, 64K, 1M (?), 16M (?) + // MIPS allows any power of 2 from 4K through 64K + + // If 64K < .p_align then we assume that 4K is also accepted. // .p_align can be like 2M, which is a huge over-estimate. // RELRO ends on a page boundary: usually close to actual page_size unsigned offset = get_te64(&phdr->p_offset); @@ -4860,7 +4876,7 @@ void PackLinuxElf64::pack1(OutputFile * /*fo*/, Filter &ft) ++b; } lg2_page = umin(lg2_page, -1+ b); - } + } } if (PT_GNU_STACK64 == type) { gnu_stack = phdr;