File: upstream-57763ca1-ELF-stubs-golang.patch

package info (click to toggle)
upx-ucl 4.2.4-1.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 16,168 kB
  • sloc: ansic: 99,906; cpp: 60,585; asm: 32,273; python: 1,573; makefile: 1,353; sh: 1,143
file content (121 lines) | stat: -rw-r--r-- 5,863 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
From: John Reiser <jreiser@BitWagon.com>
Date: Tue, 21 May 2024 17:14:21 -0700
Subject: ELf stubs: go_lang different placement of DT_STRTAB, DT_SYMTAB

https://github.com/upx/upx/issues/825
	modified:   p_lx_elf.cpp

Bugs-Debian: https://bugs.debian.org/1071591
Forwarded: not-needed
---
 src/p_lx_elf.cpp | 34 ++++++++++++++++++++++++----------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp
index 9aa664f..98fedcf 100644
--- a/src/p_lx_elf.cpp
+++ b/src/p_lx_elf.cpp
@@ -2106,7 +2106,9 @@ PackLinuxElf32::invert_pt_dynamic(Elf32_Dyn const *dynp, u32_t headway)
     unsigned const z_str = dt_table[Elf32_Dyn::DT_STRSZ];
     strtab_max = !z_str ? 0 : get_te32(&dynp0[-1+ z_str].d_val);
     unsigned const z_tab = dt_table[Elf32_Dyn::DT_STRTAB];
-    unsigned const strtab_beg = !z_tab ? 0 : get_te32(&dynp0[-1+ z_tab].d_val);
+    unsigned const strtab_beg = !z_tab ? 0
+        : elf_get_offset_from_address(get_te32(&dynp0[-1+ z_tab].d_val));
+
     if (!z_str || !z_tab
     || (this->file_size - strtab_beg) < strtab_max  // strtab overlaps EOF
         // last string in table must have terminating NUL
@@ -2121,8 +2123,14 @@ PackLinuxElf32::invert_pt_dynamic(Elf32_Dyn const *dynp, u32_t headway)
     symnum_max = elf_find_table_size(
         Elf32_Dyn::DT_SYMTAB, Elf32_Shdr::SHT_DYNSYM) / sizeof(Elf32_Sym);
 
-    unsigned const x_sym = dt_table[Elf32_Dyn::DT_SYMTAB];
-    unsigned const v_hsh = elf_unsigned_dynamic(Elf32_Dyn::DT_HASH);
+    unsigned v_sym = dt_table[Elf32_Dyn::DT_SYMTAB];
+    if (v_sym) {
+        v_sym = elf_get_offset_from_address(get_te32(&dynp0[-1+ v_sym].d_val));
+    }
+    unsigned v_hsh = dt_table[Elf32_Dyn::DT_HASH];
+    if (v_hsh) {
+        v_hsh = elf_get_offset_from_address(get_te32(&dynp0[-1+ v_hsh].d_val));
+    }
     if (v_hsh && file_image) {
         hashtab = (unsigned const *)elf_find_dynamic(Elf32_Dyn::DT_HASH);
         if (!hashtab) {
@@ -2144,7 +2152,6 @@ PackLinuxElf32::invert_pt_dynamic(Elf32_Dyn const *dynp, u32_t headway)
             throwCantPack(msg);
         }
 
-        unsigned const v_sym = !x_sym ? 0 : get_te32(&dynp0[-1+ x_sym].d_val);
         if ((unsigned)(hashend - buckets) < nbucket
         || !v_sym || (unsigned)file_size <= v_sym
         || ((v_hsh < v_sym) && (v_sym - v_hsh) < sizeof(*buckets)*(2+ nbucket))
@@ -2171,6 +2178,7 @@ PackLinuxElf32::invert_pt_dynamic(Elf32_Dyn const *dynp, u32_t headway)
     }
     unsigned const v_gsh = elf_unsigned_dynamic(Elf32_Dyn::DT_GNU_HASH);
     if (v_gsh && file_image) {
+        // Not similar to DT_HASH because DT_GNU_HASH is not small (0x6ffffef5).
         gashtab = (unsigned const *)elf_find_dynamic(Elf32_Dyn::DT_GNU_HASH);
         if (!gashtab) {
             char msg[40]; snprintf(msg, sizeof(msg),
@@ -2230,7 +2238,6 @@ PackLinuxElf32::invert_pt_dynamic(Elf32_Dyn const *dynp, u32_t headway)
         }
         bmax -= symbias;
 
-        u32_t const v_sym = !x_sym ? 0 : get_te32(&dynp0[-1+ x_sym].d_val);
         unsigned r = 0;
         if (!n_bucket || !n_bitmask || !v_sym
         || (r=1, ((-1+ n_bitmask) & n_bitmask))  // not a power of 2
@@ -8032,7 +8039,8 @@ PackLinuxElf64::invert_pt_dynamic(Elf64_Dyn const *dynp, upx_uint64_t headway)
     unsigned const z_str = dt_table[Elf64_Dyn::DT_STRSZ];
     strtab_max = !z_str ? 0 : get_te64(&dynp0[-1+ z_str].d_val);
     unsigned const z_tab = dt_table[Elf64_Dyn::DT_STRTAB];
-    unsigned const strtab_beg = !z_tab ? 0 : get_te64(&dynp0[-1+ z_tab].d_val);
+    unsigned const strtab_beg = !z_tab ? 0
+        : elf_get_offset_from_address(get_te64(&dynp0[-1+ z_tab].d_val));
     if (!z_str || !z_tab
     || (this->file_size - strtab_beg) < strtab_max  // strtab overlaps EOF
         // last string in table must have terminating NUL
@@ -8047,8 +8055,15 @@ PackLinuxElf64::invert_pt_dynamic(Elf64_Dyn const *dynp, upx_uint64_t headway)
     symnum_max = elf_find_table_size(
         Elf64_Dyn::DT_SYMTAB, Elf64_Shdr::SHT_DYNSYM) / sizeof(Elf64_Sym);
 
-    unsigned const x_sym = dt_table[Elf64_Dyn::DT_SYMTAB];
-    unsigned const v_hsh = elf_unsigned_dynamic(Elf64_Dyn::DT_HASH);
+    unsigned v_sym = dt_table[Elf64_Dyn::DT_SYMTAB];
+    if (v_sym) {
+        v_sym = elf_get_offset_from_address(get_te64(&dynp0[-1+ v_sym].d_val));
+    }
+
+    unsigned v_hsh = dt_table[Elf64_Dyn::DT_HASH];
+    if (v_hsh) {
+        v_hsh = elf_get_offset_from_address(get_te64(&dynp0[-1+ v_hsh].d_val));
+    }
     if (v_hsh && file_image) {
         hashtab = (unsigned const *)elf_find_dynamic(Elf64_Dyn::DT_HASH);
         if (!hashtab) {
@@ -8070,7 +8085,6 @@ PackLinuxElf64::invert_pt_dynamic(Elf64_Dyn const *dynp, upx_uint64_t headway)
             throwCantPack(msg);
         }
 
-        unsigned const v_sym = !x_sym ? 0 : get_te64(&dynp0[-1+ x_sym].d_val);  // UPX_RSIZE_MAX_MEM
         if ((unsigned)(hashend - buckets) < nbucket
         || !v_sym || (unsigned)file_size <= v_sym
         || ((v_hsh < v_sym) && (v_sym - v_hsh) < sizeof(*buckets)*(2+ nbucket))
@@ -8097,6 +8111,7 @@ PackLinuxElf64::invert_pt_dynamic(Elf64_Dyn const *dynp, upx_uint64_t headway)
     }
     unsigned const v_gsh = elf_unsigned_dynamic(Elf64_Dyn::DT_GNU_HASH);
     if (v_gsh && file_image) {
+        // Not similar to DT_HASH because DT_GNU_HASH is not small (0x6ffffef5).
         gashtab = (unsigned const *)elf_find_dynamic(Elf64_Dyn::DT_GNU_HASH);
         if (!gashtab) {
             char msg[40]; snprintf(msg, sizeof(msg),
@@ -8156,7 +8171,6 @@ PackLinuxElf64::invert_pt_dynamic(Elf64_Dyn const *dynp, upx_uint64_t headway)
         }
         bmax -= symbias;
 
-        upx_uint64_t const v_sym = !x_sym ? 0 : get_te64(&dynp0[-1+ x_sym].d_val);
         unsigned r = 0;
         if (!n_bucket || !n_bitmask || !v_sym
         || (r=1, ((-1+ n_bitmask) & n_bitmask))  // not a power of 2