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