git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@2443 77e5149b-7576-45b1-b177-96237e5ba77b
| ... | ... |
@@ -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); |