1From 3781df9da23840e596d5e9e8493f22666802fe6c Mon Sep 17 00:00:00 2001 2From: John Reiser <jreiser@BitWagon.com> 3Date: Fri, 11 Dec 2020 13:38:18 -0800 4Subject: [PATCH] Check DT_REL/DT_RELA, DT_RELSZ/DT_RELASZ 5 6https://github.com/upx/upx/issues/421 7 modified: p_lx_elf.cpp 8 9[Retrieved from: 10https://github.com/upx/upx/commit/3781df9da23840e596d5e9e8493f22666802fe6c] 11Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com> 12--- 13 src/p_lx_elf.cpp | 34 +++++++++++++++++++++++++++++----- 14 1 file changed, 29 insertions(+), 5 deletions(-) 15 16diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp 17index 182db192f..3a4101cf7 100644 18--- a/src/p_lx_elf.cpp 19+++ b/src/p_lx_elf.cpp 20@@ -2222,8 +2222,20 @@ bool PackLinuxElf32::canPack() 21 int z_rsz = dt_table[Elf32_Dyn::DT_RELSZ]; 22 if (z_rel && z_rsz) { 23 unsigned rel_off = get_te32(&dynseg[-1+ z_rel].d_val); 24+ if ((unsigned)file_size <= rel_off) { 25+ char msg[70]; snprintf(msg, sizeof(msg), 26+ "bad Elf32_Dynamic[DT_REL] %#x\n", 27+ rel_off); 28+ throwCantPack(msg); 29+ } 30 Elf32_Rel *rp = (Elf32_Rel *)&file_image[rel_off]; 31 unsigned relsz = get_te32(&dynseg[-1+ z_rsz].d_val); 32+ if ((unsigned)file_size <= relsz) { 33+ char msg[70]; snprintf(msg, sizeof(msg), 34+ "bad Elf32_Dynamic[DT_RELSZ] %#x\n", 35+ relsz); 36+ throwCantPack(msg); 37+ } 38 Elf32_Rel *last = (Elf32_Rel *)(relsz + (char *)rp); 39 for (; rp < last; ++rp) { 40 unsigned r_va = get_te32(&rp->r_offset); 41@@ -2562,14 +2574,26 @@ PackLinuxElf64::canPack() 42 int z_rel = dt_table[Elf64_Dyn::DT_RELA]; 43 int z_rsz = dt_table[Elf64_Dyn::DT_RELASZ]; 44 if (z_rel && z_rsz) { 45- unsigned rel_off = get_te64(&dynseg[-1+ z_rel].d_val); 46+ upx_uint64_t rel_off = get_te64(&dynseg[-1+ z_rel].d_val); 47+ if ((u64_t)file_size <= rel_off) { 48+ char msg[70]; snprintf(msg, sizeof(msg), 49+ "bad Elf64_Dynamic[DT_RELA] %#llx\n", 50+ rel_off); 51+ throwCantPack(msg); 52+ } 53 Elf64_Rela *rp = (Elf64_Rela *)&file_image[rel_off]; 54- unsigned relsz = get_te64(&dynseg[-1+ z_rsz].d_val); 55+ upx_uint64_t relsz = get_te64(&dynseg[-1+ z_rsz].d_val); 56+ if ((u64_t)file_size <= relsz) { 57+ char msg[70]; snprintf(msg, sizeof(msg), 58+ "bad Elf64_Dynamic[DT_RELASZ] %#llx\n", 59+ relsz); 60+ throwCantPack(msg); 61+ } 62 Elf64_Rela *last = (Elf64_Rela *)(relsz + (char *)rp); 63 for (; rp < last; ++rp) { 64- unsigned r_va = get_te64(&rp->r_offset); 65+ upx_uint64_t r_va = get_te64(&rp->r_offset); 66 if (r_va == user_init_ava) { // found the Elf64_Rela 67- unsigned r_info = get_te64(&rp->r_info); 68+ upx_uint64_t r_info = get_te64(&rp->r_info); 69 unsigned r_type = ELF64_R_TYPE(r_info); 70 if (Elf64_Ehdr::EM_AARCH64 == e_machine 71 && R_AARCH64_RELATIVE == r_type) { 72@@ -2581,7 +2605,7 @@ PackLinuxElf64::canPack() 73 } 74 else { 75 char msg[50]; snprintf(msg, sizeof(msg), 76- "bad relocation %#x DT_INIT_ARRAY[0]", 77+ "bad relocation %#llx DT_INIT_ARRAY[0]", 78 r_info); 79 throwCantPack(msg); 80 } 81