git-svn: trunk@2443
Tomasz Kojm authored on 2006/10/28 22:55:28... | ... |
@@ -1,3 +1,8 @@ |
1 |
+Sat Oct 28 15:52:42 CEST 2006 (tk) |
|
2 |
+---------------------------------- |
|
3 |
+ * libclamav/elf.c: make the code reentrant (closes bug#57) |
|
4 |
+ Reported by Robert Allerstorfer <roal*anet.at> |
|
5 |
+ |
|
1 | 6 |
Sat Oct 28 14:54:00 CEST 2006 (tk) |
2 | 7 |
---------------------------------- |
3 | 8 |
* libclamav/others.h: include clamav.h (closes bug#101) |
... | ... |
@@ -37,19 +37,17 @@ |
37 | 37 |
#include "clamav.h" |
38 | 38 |
#include "execs.h" |
39 | 39 |
|
40 |
-static short need_conversion = 0; |
|
41 |
- |
|
42 |
-static inline uint16_t EC16(uint16_t v) |
|
40 |
+static inline uint16_t EC16(uint16_t v, uint8_t c) |
|
43 | 41 |
{ |
44 |
- if(!need_conversion) |
|
42 |
+ if(!c) |
|
45 | 43 |
return v; |
46 | 44 |
else |
47 | 45 |
return ((v >> 8) + (v << 8)); |
48 | 46 |
} |
49 | 47 |
|
50 |
-static inline uint32_t EC32(uint32_t v) |
|
48 |
+static inline uint32_t EC32(uint32_t v, uint8_t c) |
|
51 | 49 |
{ |
52 |
- if(!need_conversion) |
|
50 |
+ if(!c) |
|
53 | 51 |
return v; |
54 | 52 |
else |
55 | 53 |
return ((v >> 24) | ((v & 0x00FF0000) >> 8) | ((v & 0x0000FF00) << 8) | (v << 24)); |
... | ... |
@@ -61,6 +59,7 @@ int cli_scanelf(int desc, cli_ctx *ctx) |
61 | 61 |
struct elf_section_hdr32 *section_hdr; |
62 | 62 |
uint16_t shnum, shentsize; |
63 | 63 |
uint32_t entry, shoff, image; |
64 |
+ uint8_t conv = 0; |
|
64 | 65 |
int i; |
65 | 66 |
|
66 | 67 |
cli_dbgmsg("in cli_scanelf\n"); |
... | ... |
@@ -87,19 +86,19 @@ int cli_scanelf(int desc, cli_ctx *ctx) |
87 | 87 |
cli_dbgmsg("ELF: File is little-endian - conversion not required\n"); |
88 | 88 |
#else |
89 | 89 |
cli_dbgmsg("ELF: File is little-endian - data conversion enabled\n"); |
90 |
- need_conversion = 1; |
|
90 |
+ conv = 1; |
|
91 | 91 |
#endif |
92 | 92 |
} else { |
93 | 93 |
image = 0x10000; |
94 | 94 |
#if WORDS_BIGENDIAN == 0 |
95 | 95 |
cli_dbgmsg("ELF: File is big-endian - data conversion enabled\n"); |
96 |
- need_conversion = 1; |
|
96 |
+ conv = 1; |
|
97 | 97 |
#else |
98 | 98 |
cli_dbgmsg("ELF: File is big-endian - conversion not required\n"); |
99 | 99 |
#endif |
100 | 100 |
} |
101 | 101 |
|
102 |
- switch(EC16(file_hdr.e_type)) { |
|
102 |
+ switch(EC16(file_hdr.e_type, conv)) { |
|
103 | 103 |
case 0x0: /* ET_NONE */ |
104 | 104 |
cli_dbgmsg("ELF: File type: None\n"); |
105 | 105 |
break; |
... | ... |
@@ -116,10 +115,10 @@ int cli_scanelf(int desc, cli_ctx *ctx) |
116 | 116 |
cli_dbgmsg("ELF: File type: Core\n"); |
117 | 117 |
break; |
118 | 118 |
default: |
119 |
- cli_dbgmsg("ELF: File type: Unknown (%d)\n", EC16(file_hdr.e_type)); |
|
119 |
+ cli_dbgmsg("ELF: File type: Unknown (%d)\n", EC16(file_hdr.e_type, conv)); |
|
120 | 120 |
} |
121 | 121 |
|
122 |
- switch(EC16(file_hdr.e_machine)) { |
|
122 |
+ switch(EC16(file_hdr.e_machine, conv)) { |
|
123 | 123 |
/* Due to a huge list, we only include the most popular machines here */ |
124 | 124 |
case 0x0: /* EM_NONE */ |
125 | 125 |
cli_dbgmsg("ELF: Machine type: None\n"); |
... | ... |
@@ -161,14 +160,14 @@ int cli_scanelf(int desc, cli_ctx *ctx) |
161 | 161 |
cli_dbgmsg("ELF: Machine type: IA64\n"); |
162 | 162 |
break; |
163 | 163 |
default: |
164 |
- cli_dbgmsg("ELF: Machine type: Unknown (%d)\n", EC16(file_hdr.e_machine)); |
|
164 |
+ cli_dbgmsg("ELF: Machine type: Unknown (%d)\n", EC16(file_hdr.e_machine, conv)); |
|
165 | 165 |
} |
166 | 166 |
|
167 |
- entry = EC32(file_hdr.e_entry); |
|
167 |
+ entry = EC32(file_hdr.e_entry, conv); |
|
168 | 168 |
cli_dbgmsg("ELF: Entry point address: 0x%.8x\n", entry); |
169 | 169 |
cli_dbgmsg("ELF: Entry point offset: 0x%.8x (%d)\n", entry - image, entry - image); |
170 | 170 |
|
171 |
- shnum = EC16(file_hdr.e_shnum); |
|
171 |
+ shnum = EC16(file_hdr.e_shnum, conv); |
|
172 | 172 |
cli_dbgmsg("ELF: Number of sections: %d\n", shnum); |
173 | 173 |
if(shnum > 256) { |
174 | 174 |
cli_dbgmsg("ELF: Suspicious number of sections\n"); |
... | ... |
@@ -180,7 +179,7 @@ int cli_scanelf(int desc, cli_ctx *ctx) |
180 | 180 |
return CL_EFORMAT; |
181 | 181 |
} |
182 | 182 |
|
183 |
- shentsize = EC16(file_hdr.e_shentsize); |
|
183 |
+ shentsize = EC16(file_hdr.e_shentsize, conv); |
|
184 | 184 |
if(shentsize != sizeof(struct elf_section_hdr32)) { |
185 | 185 |
cli_dbgmsg("ELF: shentsize != sizeof(struct elf_section_hdr32)\n"); |
186 | 186 |
if(DETECT_BROKEN) { |
... | ... |
@@ -191,7 +190,7 @@ int cli_scanelf(int desc, cli_ctx *ctx) |
191 | 191 |
return CL_EFORMAT; |
192 | 192 |
} |
193 | 193 |
|
194 |
- shoff = EC32(file_hdr.e_shoff); |
|
194 |
+ shoff = EC32(file_hdr.e_shoff, conv); |
|
195 | 195 |
cli_dbgmsg("ELF: Section header table offset: %d\n", shoff); |
196 | 196 |
if((uint32_t) lseek(desc, shoff, SEEK_SET) != shoff) { |
197 | 197 |
/* Possibly broken end of file */ |
... | ... |
@@ -226,10 +225,10 @@ int cli_scanelf(int desc, cli_ctx *ctx) |
226 | 226 |
} |
227 | 227 |
|
228 | 228 |
cli_dbgmsg("ELF: Section %d\n", i); |
229 |
- cli_dbgmsg("ELF: Section offset: %d\n", EC32(section_hdr[i].sh_offset)); |
|
230 |
- cli_dbgmsg("ELF: Section size: %d\n", EC32(section_hdr[i].sh_size)); |
|
229 |
+ cli_dbgmsg("ELF: Section offset: %d\n", EC32(section_hdr[i].sh_offset, conv)); |
|
230 |
+ cli_dbgmsg("ELF: Section size: %d\n", EC32(section_hdr[i].sh_size, conv)); |
|
231 | 231 |
|
232 |
- switch(EC32(section_hdr[i].sh_type)) { |
|
232 |
+ switch(EC32(section_hdr[i].sh_type, conv)) { |
|
233 | 233 |
case 0x6: /* SHT_DYNAMIC */ |
234 | 234 |
cli_dbgmsg("ELF: Section type: Dynamic linking information\n"); |
235 | 235 |
break; |
... | ... |
@@ -285,13 +284,13 @@ int cli_scanelf(int desc, cli_ctx *ctx) |
285 | 285 |
cli_dbgmsg("ELF: Section type: Unknown\n"); |
286 | 286 |
} |
287 | 287 |
|
288 |
- if(EC32(section_hdr[i].sh_flags) & 0x1) /* SHF_WRITE */ |
|
288 |
+ if(EC32(section_hdr[i].sh_flags, conv) & 0x1) /* SHF_WRITE */ |
|
289 | 289 |
cli_dbgmsg("ELF: Section contains writable data\n"); |
290 | 290 |
|
291 |
- if(EC32(section_hdr[i].sh_flags) & 0x2) /* SHF_ALLOC */ |
|
291 |
+ if(EC32(section_hdr[i].sh_flags, conv) & 0x2) /* SHF_ALLOC */ |
|
292 | 292 |
cli_dbgmsg("ELF: Section occupies memory\n"); |
293 | 293 |
|
294 |
- if(EC32(section_hdr[i].sh_flags) & 0x4) /* SHF_EXECINSTR */ |
|
294 |
+ if(EC32(section_hdr[i].sh_flags, conv) & 0x4) /* SHF_EXECINSTR */ |
|
295 | 295 |
cli_dbgmsg("ELF: Section contains executable code\n"); |
296 | 296 |
|
297 | 297 |
cli_dbgmsg("------------------------------------\n"); |
... | ... |
@@ -307,6 +306,7 @@ int cli_elfheader(int desc, struct cli_exe_info *elfinfo) |
307 | 307 |
struct elf_section_hdr32 *section_hdr; |
308 | 308 |
uint16_t shnum, shentsize; |
309 | 309 |
uint32_t entry, shoff, image; |
310 |
+ uint8_t conv = 0; |
|
310 | 311 |
int i; |
311 | 312 |
|
312 | 313 |
cli_dbgmsg("in cli_elfheader\n"); |
... | ... |
@@ -330,31 +330,31 @@ int cli_elfheader(int desc, struct cli_exe_info *elfinfo) |
330 | 330 |
if(file_hdr.e_ident[5] == 1) { |
331 | 331 |
image = 0x8048000; |
332 | 332 |
#if WORDS_BIGENDIAN == 1 |
333 |
- need_conversion = 1; |
|
333 |
+ conv = 1; |
|
334 | 334 |
#endif |
335 | 335 |
} else { |
336 | 336 |
image = 0x10000; |
337 | 337 |
#if WORDS_BIGENDIAN == 0 |
338 |
- need_conversion = 1; |
|
338 |
+ conv = 1; |
|
339 | 339 |
#endif |
340 | 340 |
} |
341 | 341 |
|
342 |
- entry = EC32(file_hdr.e_entry); |
|
342 |
+ entry = EC32(file_hdr.e_entry, conv); |
|
343 | 343 |
|
344 |
- shnum = EC16(file_hdr.e_shnum); |
|
344 |
+ shnum = EC16(file_hdr.e_shnum, conv); |
|
345 | 345 |
if(shnum > 256) { |
346 | 346 |
cli_dbgmsg("ELF: Suspicious number of sections\n"); |
347 | 347 |
return -1; |
348 | 348 |
} |
349 | 349 |
elfinfo->nsections = shnum; |
350 | 350 |
|
351 |
- shentsize = EC16(file_hdr.e_shentsize); |
|
351 |
+ shentsize = EC16(file_hdr.e_shentsize, conv); |
|
352 | 352 |
if(shentsize != sizeof(struct elf_section_hdr32)) { |
353 | 353 |
cli_dbgmsg("ELF: shentsize != sizeof(struct elf_section_hdr32)\n"); |
354 | 354 |
return -1; |
355 | 355 |
} |
356 | 356 |
|
357 |
- shoff = EC32(file_hdr.e_shoff); |
|
357 |
+ shoff = EC32(file_hdr.e_shoff, conv); |
|
358 | 358 |
if((uint32_t) lseek(desc, shoff, SEEK_SET) != shoff) { |
359 | 359 |
/* Possibly broken end of file */ |
360 | 360 |
return -1; |
... | ... |
@@ -380,9 +380,9 @@ int cli_elfheader(int desc, struct cli_exe_info *elfinfo) |
380 | 380 |
return -1; |
381 | 381 |
} |
382 | 382 |
|
383 |
- elfinfo->section[i].rva = EC32(section_hdr[i].sh_addr); |
|
384 |
- elfinfo->section[i].raw = EC32(section_hdr[i].sh_offset); |
|
385 |
- elfinfo->section[i].rsz = EC32(section_hdr[i].sh_size); |
|
383 |
+ elfinfo->section[i].rva = EC32(section_hdr[i].sh_addr, conv); |
|
384 |
+ elfinfo->section[i].raw = EC32(section_hdr[i].sh_offset, conv); |
|
385 |
+ elfinfo->section[i].rsz = EC32(section_hdr[i].sh_size, conv); |
|
386 | 386 |
} |
387 | 387 |
|
388 | 388 |
free(section_hdr); |