rpms/clamav/F-7 clamav-0.92.1-CVE-2008-0314.diff, NONE, 1.1 clamav-0.92.1-CVE-2008-1100.diff, NONE, 1.1 clamav-0.92.1-CVE-2008-1387.diff, NONE, 1.1 clamav-0.92.1-CVE-2008-1833.diff, NONE, 1.1 clamav.spec, 1.65, 1.66
Tomas Hoger (thoger)
fedora-extras-commits at redhat.com
Fri Apr 25 10:08:10 UTC 2008
- Previous message (by thread): rpms/clamav/F-8 clamav-0.92.1-CVE-2008-0314.diff, NONE, 1.1 clamav-0.92.1-CVE-2008-1100.diff, NONE, 1.1 clamav-0.92.1-CVE-2008-1387.diff, NONE, 1.1 clamav-0.92.1-CVE-2008-1833.diff, NONE, 1.1 clamav.spec, 1.67, 1.68
- Next message (by thread): rpms/speex/devel speex.spec,1.24,1.25
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: thoger
Update of /cvs/extras/rpms/clamav/F-7
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv28756
Modified Files:
clamav.spec
Added Files:
clamav-0.92.1-CVE-2008-0314.diff
clamav-0.92.1-CVE-2008-1100.diff
clamav-0.92.1-CVE-2008-1387.diff
clamav-0.92.1-CVE-2008-1833.diff
Log Message:
- Security update - backport security fixes from 0.93:
CVE-2008-1100 (#442360): Upack Processing Buffer Overflow Vulnerability
CVE-2008-1387 (#442525): Endless loop / hang with crafted arj
CVE-2008-0314 (#442740): PeSpin Heap Overflow Vulnerability
CVE-2008-1833 (#442741): PE WWPack Heap Overflow Vulnerability
clamav-0.92.1-CVE-2008-0314.diff:
--- NEW FILE clamav-0.92.1-CVE-2008-0314.diff ---
diff -pruN clamav-0.92.1.orig/libclamav/spin.c clamav-0.92.1/libclamav/spin.c
--- clamav-0.92.1.orig/libclamav/spin.c 2007-12-06 13:59:04.000000000 +0100
+++ clamav-0.92.1/libclamav/spin.c 2008-04-24 19:16:26.000000000 +0200
@@ -419,7 +419,7 @@ int unspin(char *src, int ssize, struct
/* len = cli_readint32(ep+0x2fc8); -- Using vsizes instead */
for (j=0; j<sectcnt; j++) {
- if (sections[j].rva <= key32 && sections[j].rva+sections[j].rsz > key32)
+ if (sections[j].rva <= key32 && key32-sections[j].rva < sections[j].vsz && CLI_ISCONTAINED(src + sections[j].raw, sections[j].rsz, src + sections[j].raw, key32 - sections[j].rva))
break;
}
clamav-0.92.1-CVE-2008-1100.diff:
--- NEW FILE clamav-0.92.1-CVE-2008-1100.diff ---
diff -pruN clamav-0.92.1.orig/libclamav/pe.c clamav-0.92.1/libclamav/pe.c
--- clamav-0.92.1.orig/libclamav/pe.c 2008-02-06 16:48:03.000000000 +0100
+++ clamav-0.92.1/libclamav/pe.c 2008-04-24 19:19:19.000000000 +0200
@@ -1246,7 +1246,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
CLI_UNPSIZELIMITS("Upack", MAX(MAX(dsize, ssize), exe_sections[1].ursz));
- if (exe_sections[1].rva - off > dsize || exe_sections[1].rva - off > dsize - exe_sections[1].ursz || (upack && (exe_sections[2].rva - exe_sections[0].rva > dsize || exe_sections[2].rva - exe_sections[0].rva > dsize - ssize)) || ssize > dsize) {
+ if (!CLI_ISCONTAINED(0, dsize, exe_sections[1].rva - off, exe_sections[1].ursz) || (upack && !CLI_ISCONTAINED(0, dsize, exe_sections[2].rva - exe_sections[0].rva, ssize)) || ssize > dsize) {
cli_dbgmsg("Upack: probably malformed pe-header, skipping to next unpacker\n");
break;
}
clamav-0.92.1-CVE-2008-1387.diff:
--- NEW FILE clamav-0.92.1-CVE-2008-1387.diff ---
diff -pruN clamav-0.92.1.orig/libclamav/unarj.c clamav-0.92.1/libclamav/unarj.c
--- clamav-0.92.1.orig/libclamav/unarj.c 2008-02-06 16:14:24.000000000 +0100
+++ clamav-0.92.1/libclamav/unarj.c 2008-04-24 19:20:59.000000000 +0200
@@ -160,6 +160,7 @@ typedef struct arj_decode_tag {
uint16_t c_table[CTABLESIZE];
unsigned char pt_len[NPT];
uint16_t pt_table[PTABLESIZE];
+ int status;
} arj_decode_t;
static int fill_buf(arj_decode_t *decode_data, int n)
@@ -170,6 +171,7 @@ static int fill_buf(arj_decode_t *decode
if (decode_data->comp_size != 0) {
decode_data->comp_size--;
if (cli_readn(decode_data->fd, &decode_data->sub_bit_buf, 1) != 1) {
+ decode_data->status = CL_EIO;
return CL_EIO;
}
} else {
@@ -228,6 +230,7 @@ static int make_table(arj_decode_t *deco
for (i = 0; (int)i < nchar; i++) {
if (bitlen[i] >= 17) {
cli_dbgmsg("UNARJ: bounds exceeded\n");
+ decode_data->status = CL_EARJ;
return CL_EARJ;
}
count[bitlen[i]]++;
@@ -238,12 +241,14 @@ static int make_table(arj_decode_t *deco
start[i+1] = start[i] + (count[i] << (16 - i));
}
if (start[17] != (unsigned short) (1 << 16)) {
+ decode_data->status = CL_EARJ;
return CL_EARJ;
}
jutbits = 16 - tablebits;
if (tablebits >= 17) {
cli_dbgmsg("UNARJ: bounds exceeded\n");
+ decode_data->status = CL_EARJ;
return CL_EARJ;
}
for (i = 1; (int)i <= tablebits; i++) {
@@ -261,6 +266,7 @@ static int make_table(arj_decode_t *deco
while (i != k) {
if (i >= tablesize) {
cli_dbgmsg("UNARJ: bounds exceeded\n");
+ decode_data->status = CL_EARJ;
return CL_EARJ;
}
table[i++] = 0;
@@ -275,12 +281,14 @@ static int make_table(arj_decode_t *deco
}
if (len >= 17) {
cli_dbgmsg("UNARJ: bounds exceeded\n");
+ decode_data->status = CL_EARJ;
return CL_EARJ;
}
k = start[len];
nextcode = k + weight[len];
if ((int)len <= tablebits) {
if (nextcode > (unsigned int) tablesize) {
+ decode_data->status = CL_EARJ;
return CL_EARJ;
}
for (i = start[len]; i < nextcode; i++) {
@@ -293,6 +301,7 @@ static int make_table(arj_decode_t *deco
if (*p == 0) {
if (avail >= (2 * NC - 1)) {
cli_dbgmsg("UNARJ: bounds exceeded\n");
+ decode_data->status = CL_EARJ;
return CL_EARJ;
}
decode_data->right[avail] = decode_data->left[avail] = 0;
@@ -300,6 +309,7 @@ static int make_table(arj_decode_t *deco
}
if (*p >= (2 * NC - 1)) {
cli_dbgmsg("UNARJ: bounds exceeded\n");
+ decode_data->status = CL_EARJ;
return CL_EARJ;
}
if (k & mask) {
@@ -317,7 +327,7 @@ static int make_table(arj_decode_t *deco
return CL_SUCCESS;
}
-static void read_pt_len(arj_decode_t *decode_data, int nn, int nbit, int i_special)
+static int read_pt_len(arj_decode_t *decode_data, int nn, int nbit, int i_special)
{
int i, n;
short c;
@@ -327,7 +337,8 @@ static void read_pt_len(arj_decode_t *de
if (n == 0) {
if (nn > NPT) {
cli_dbgmsg("UNARJ: bounds exceeded\n");
- return;
+ decode_data->status = CL_EARJ;
+ return CL_EARJ;
}
c = arj_getbits(decode_data, nbit);
for (i = 0; i < nn; i++) {
@@ -348,9 +359,15 @@ static void read_pt_len(arj_decode_t *de
}
}
fill_buf(decode_data, (c < 7) ? 3 : (int)(c - 3));
+ if (decode_data->status != CL_SUCCESS) {
+ return decode_data->status;
+ }
decode_data->pt_len[i++] = (unsigned char) c;
if (i == i_special) {
c = arj_getbits(decode_data, 2);
+ if (decode_data->status != CL_SUCCESS) {
+ return decode_data->status;
+ }
while ((--c >= 0) && (i < NPT)) {
decode_data->pt_len[i++] = 0;
}
@@ -359,8 +376,11 @@ static void read_pt_len(arj_decode_t *de
while ((i < nn) && (i < NPT)) {
decode_data->pt_len[i++] = 0;
}
- make_table(decode_data, nn, decode_data->pt_len, 8, decode_data->pt_table, PTABLESIZE);
+ if (make_table(decode_data, nn, decode_data->pt_len, 8, decode_data->pt_table, PTABLESIZE) != CL_SUCCESS) {
+ return CL_EARJ;
+ }
}
+ return CL_SUCCESS;
}
static int read_c_len(arj_decode_t *decode_data)
@@ -369,8 +389,14 @@ static int read_c_len(arj_decode_t *deco
unsigned short mask;
n = arj_getbits(decode_data, CBIT);
+ if (decode_data->status != CL_SUCCESS) {
+ return decode_data->status;
+ }
if (n == 0) {
c = arj_getbits(decode_data, CBIT);
+ if (decode_data->status != CL_SUCCESS) {
+ return decode_data->status;
+ }
for (i = 0; i < NC; i++) {
decode_data->c_len[i] = 0;
}
@@ -386,6 +412,7 @@ static int read_c_len(arj_decode_t *deco
do {
if (c >= (2 * NC - 1)) {
cli_warnmsg("ERROR: bounds exceeded\n");
+ decode_data->status = CL_EFORMAT;
return CL_EFORMAT;
}
if (decode_data->bit_buf & mask) {
@@ -398,9 +425,13 @@ static int read_c_len(arj_decode_t *deco
}
if (c >= 19) {
cli_dbgmsg("UNARJ: bounds exceeded\n");
+ decode_data->status = CL_EARJ;
return CL_EARJ;
}
fill_buf(decode_data, (int)(decode_data->pt_len[c]));
+ if (decode_data->status != CL_SUCCESS) {
+ return decode_data->status;
+ }
if (c <= 2) {
if (c == 0) {
c = 1;
@@ -409,9 +440,13 @@ static int read_c_len(arj_decode_t *deco
} else {
c = arj_getbits(decode_data, CBIT) + 20;
}
+ if (decode_data->status != CL_SUCCESS) {
+ return decode_data->status;
+ }
while (--c >= 0) {
if (i >= NC) {
cli_warnmsg("ERROR: bounds exceeded\n");
+ decode_data->status = CL_EFORMAT;
return CL_EFORMAT;
}
decode_data->c_len[i++] = 0;
@@ -419,6 +454,7 @@ static int read_c_len(arj_decode_t *deco
} else {
if (i >= NC) {
cli_warnmsg("ERROR: bounds exceeded\n");
+ decode_data->status = CL_EFORMAT;
return CL_EFORMAT;
}
decode_data->c_len[i++] = (unsigned char) (c - 2);
@@ -427,7 +463,9 @@ static int read_c_len(arj_decode_t *deco
while (i < NC) {
decode_data->c_len[i++] = 0;
}
- make_table(decode_data, NC, decode_data->c_len, 12, decode_data->c_table, CTABLESIZE);
+ if (make_table(decode_data, NC, decode_data->c_len, 12, decode_data->c_table, CTABLESIZE) != CL_SUCCESS) {
+ return CL_EARJ;
+ }
}
return CL_SUCCESS;
}
@@ -450,6 +488,7 @@ static uint16_t decode_c(arj_decode_t *d
do {
if (j >= (2 * NC - 1)) {
cli_warnmsg("ERROR: bounds exceeded\n");
+ decode_data->status = CL_EARJ;
return 0;
}
if (decode_data->bit_buf & mask) {
@@ -474,6 +513,7 @@ static uint16_t decode_p(arj_decode_t *d
do {
if (j >= (2 * NC - 1)) {
cli_warnmsg("ERROR: bounds exceeded\n");
+ decode_data->status = CL_EARJ;
return 0;
}
if (decode_data->bit_buf & mask) {
@@ -508,8 +548,10 @@ static int decode(int fd, arj_metadata_t
decode_data.comp_size = metadata->comp_size;
ret = decode_start(&decode_data);
if (ret != CL_SUCCESS) {
+ free(decode_data.text);
return ret;
}
+ decode_data.status = CL_SUCCESS;
while (count < metadata->orig_size) {
if ((chr = decode_c(&decode_data)) <= UCHAR_MAX) {
@@ -517,7 +559,10 @@ static int decode(int fd, arj_metadata_t
count++;
if (++out_ptr >= DDICSIZ) {
out_ptr = 0;
- write_text(metadata->ofd, decode_data.text, DDICSIZ);
+ if (write_text(metadata->ofd, decode_data.text, DDICSIZ) != CL_SUCCESS) {
+ free(decode_data.text);
+ return CL_EIO;
+ }
}
} else {
j = chr - (UCHAR_MAX + 1 - THRESHOLD);
@@ -539,7 +584,10 @@ static int decode(int fd, arj_metadata_t
decode_data.text[out_ptr] = decode_data.text[i];
if (++out_ptr >= DDICSIZ) {
out_ptr = 0;
- write_text(metadata->ofd, decode_data.text, DDICSIZ);
+ if (write_text(metadata->ofd, decode_data.text, DDICSIZ) != CL_SUCCESS) {
+ free(decode_data.text);
+ return CL_EIO;
+ }
}
if (++i >= DDICSIZ) {
i = 0;
@@ -547,6 +595,10 @@ static int decode(int fd, arj_metadata_t
}
}
}
+ if (decode_data.status != CL_SUCCESS) {
+ free(decode_data.text);
+ return decode_data.status;
+ }
}
if (out_ptr != 0) {
write_text(metadata->ofd, decode_data.text, out_ptr);
@@ -623,21 +675,37 @@ static int decode_f(int fd, arj_metadata
return ret;
}
decode_data.getlen = decode_data.getbuf = 0;
-
+ decode_data.status = CL_SUCCESS;
+
while (count < metadata->orig_size) {
chr = decode_len(&decode_data);
+ if (decode_data.status != CL_SUCCESS) {
+ free(decode_data.text);
+ return decode_data.status;
+ }
if (chr == 0) {
ARJ_GETBITS(dd, chr, CHAR_BIT);
+ if (decode_data.status != CL_SUCCESS) {
+ free(decode_data.text);
+ return decode_data.status;
+ }
decode_data.text[out_ptr] = (unsigned char) chr;
count++;
if (++out_ptr >= DDICSIZ) {
out_ptr = 0;
- write_text(metadata->ofd, decode_data.text, DDICSIZ);
+ if (write_text(metadata->ofd, decode_data.text, DDICSIZ) != CL_SUCCESS) {
+ free(decode_data.text);
+ return CL_EIO;
+ }
}
} else {
j = chr - 1 + THRESHOLD;
count += j;
pos = decode_ptr(&decode_data);
+ if (decode_data.status != CL_SUCCESS) {
+ free(decode_data.text);
+ return decode_data.status;
+ }
if ((i = out_ptr - pos - 1) < 0) {
i += DDICSIZ;
}
@@ -649,7 +717,10 @@ static int decode_f(int fd, arj_metadata
decode_data.text[out_ptr] = decode_data.text[i];
if (++out_ptr >= DDICSIZ) {
out_ptr = 0;
- write_text(metadata->ofd, decode_data.text, DDICSIZ);
+ if (write_text(metadata->ofd, decode_data.text, DDICSIZ) != CL_SUCCESS) {
+ free(decode_data.text);
+ return CL_EIO;
+ }
}
if (++i >= DDICSIZ) {
i = 0;
@@ -1010,10 +1081,10 @@ int cli_unarj_extract_file(int fd, const
case 1:
case 2:
case 3:
- decode(fd, metadata);
+ ret = decode(fd, metadata);
break;
case 4:
- decode_f(fd, metadata);
+ ret = decode_f(fd, metadata);
break;
default:
ret = CL_EFORMAT;
clamav-0.92.1-CVE-2008-1833.diff:
--- NEW FILE clamav-0.92.1-CVE-2008-1833.diff ---
diff -pruN clamav-0.92.1.orig/libclamav/pe.c clamav-0.92.1/libclamav/pe.c
--- clamav-0.92.1.orig/libclamav/pe.c 2008-02-06 16:48:03.000000000 +0100
+++ clamav-0.92.1/libclamav/pe.c 2008-04-24 19:37:34.000000000 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 - 2006 Tomasz Kojm <tkojm at clamav.net>
+ * Copyright (C) 2004 - 2007 Tomasz Kojm <tkojm at clamav.net>
* aCaB <acab at clamav.net>
*
* This program is free software; you can redistribute it and/or modify
@@ -23,11 +23,12 @@
#endif
#include <stdio.h>
+#if HAVE_STRING_H
#include <string.h>
+#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -1861,106 +1862,65 @@ int cli_scanpe(int desc, cli_ctx *ctx)
CLI_UNPRESULTS("yC",(yc_decrypt(spinned, fsize, exe_sections, nsections-1, e_lfanew, ndesc)),0,(spinned,0));
}
-
/* WWPack */
- if((DCONF & PE_CONF_WWPACK) && nsections > 1 &&
- exe_sections[nsections-1].raw>0x2b1 &&
+ while ((DCONF & PE_CONF_WWPACK) && nsections > 1 &&
vep == exe_sections[nsections - 1].rva &&
- exe_sections[nsections - 1].rva + exe_sections[nsections - 1].rsz == max &&
memcmp(epbuff, "\x53\x55\x8b\xe8\x33\xdb\xeb", 7) == 0 &&
memcmp(epbuff+0x68, "\xe8\x00\x00\x00\x00\x58\x2d\x6d\x00\x00\x00\x50\x60\x33\xc9\x50\x58\x50\x50", 19) == 0) {
- uint32_t headsize=exe_sections[nsections - 1].raw;
- char *dest, *wwp;
+ uint32_t head = exe_sections[nsections - 1].raw;
+ uint8_t *packer;
- for(i = 0 ; i < (unsigned int)nsections-1; i++)
- if (exe_sections[i].raw<headsize) headsize=exe_sections[i].raw;
-
- dsize = max-min+headsize-exe_sections[nsections - 1].rsz;
+ ssize = 0;
+ for(i=0 ; ; i++) {
+ if(exe_sections[i].raw<head)
+ head=exe_sections[i].raw;
+ if(i==nsections-1) break;
+ if(ssize<exe_sections[i].rva+exe_sections[i].vsz)
+ ssize=exe_sections[i].rva+exe_sections[i].vsz;
+ }
+ if(!head || !ssize || head>ssize) break;
- CLI_UNPSIZELIMITS("WWPack", dsize);
+ CLI_UNPSIZELIMITS("WWPack", ssize);
- if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
- cli_dbgmsg("WWPack: Can't allocate %d bytes\n", dsize);
+ if(!(src=(char *)cli_calloc(ssize, sizeof(char)))) {
free(exe_sections);
return CL_EMEM;
}
-
lseek(desc, 0, SEEK_SET);
- if((size_t) cli_readn(desc, dest, headsize) != headsize) {
- cli_dbgmsg("WWPack: Can't read %d bytes from headers\n", headsize);
- free(dest);
+ if((size_t) cli_readn(desc, src, head) != head) {
+ cli_dbgmsg("WWPack: Can't read %d bytes from headers\n", head);
+ free(src);
free(exe_sections);
return CL_EIO;
}
-
- for(i = 0 ; i < (unsigned int)nsections-1; i++) {
- if(exe_sections[i].rsz) {
- if(!cli_seeksect(desc, &exe_sections[i]) || (unsigned int) cli_readn(desc, dest + headsize + exe_sections[i].rva - min, exe_sections[i].rsz) != exe_sections[i].rsz) {
- free(dest);
- free(exe_sections);
- return CL_EIO;
- }
- }
- }
-
- if((wwp = (char *) cli_calloc(exe_sections[nsections - 1].rsz, sizeof(char))) == NULL) {
- cli_dbgmsg("WWPack: Can't allocate %d bytes\n", exe_sections[nsections - 1].rsz);
- free(dest);
+ for(i = 0 ; i < (unsigned int)nsections-1; i++) {
+ if(!exe_sections[i].rsz) continue;
+ if(!cli_seeksect(desc, &exe_sections[i])) break;
+ if(!CLI_ISCONTAINED(src, ssize, src+exe_sections[i].rva, exe_sections[i].rsz)) break;
+ if(cli_readn(desc, src+exe_sections[i].rva, exe_sections[i].rsz)!=exe_sections[i].rsz) break;
+ }
+ if(i!=nsections-1) {
+ cli_dbgmsg("WWpack: Probably hacked/damaged file.\n");
+ free(src);
+ break;
+ }
+ if((packer = (char *) cli_calloc(exe_sections[nsections - 1].rsz, sizeof(char))) == NULL) {
+ free(src);
free(exe_sections);
return CL_EMEM;
}
-
- if(!cli_seeksect(desc, &exe_sections[nsections - 1]) || (size_t) cli_readn(desc, wwp, exe_sections[nsections - 1].rsz) != exe_sections[nsections - 1].rsz) {
+ if(!cli_seeksect(desc, &exe_sections[nsections - 1]) || (size_t) cli_readn(desc, packer, exe_sections[nsections - 1].rsz) != exe_sections[nsections - 1].rsz) {
cli_dbgmsg("WWPack: Can't read %d bytes from wwpack sect\n", exe_sections[nsections - 1].rsz);
- free(dest);
- free(wwp);
+ free(src);
+ free(packer);
free(exe_sections);
return CL_EIO;
}
- if (!wwunpack(dest, dsize, headsize, min, exe_sections[nsections-1].rva, e_lfanew, wwp, exe_sections[nsections - 1].rsz, nsections-1)) {
-
- free(wwp);
-
- CLI_UNPTEMP("WWPack",(dest,exe_sections,0));
-
- if((unsigned int) write(ndesc, dest, dsize) != dsize) {
- cli_dbgmsg("WWPack: Can't write %d bytes\n", dsize);
- close(ndesc);
- free(tempfile);
- free(dest);
- free(exe_sections);
- return CL_EIO;
- }
-
- free(dest);
- if (cli_leavetemps_flag)
- cli_dbgmsg("WWPack: Unpacked and rebuilt executable saved in %s\n", tempfile);
- else
- cli_dbgmsg("WWPack: Unpacked and rebuilt executable\n");
-
- fsync(ndesc);
- lseek(ndesc, 0, SEEK_SET);
-
- if(cli_magic_scandesc(ndesc, ctx) == CL_VIRUS) {
- free(exe_sections);
- close(ndesc);
- if(!cli_leavetemps_flag)
- unlink(tempfile);
- free(tempfile);
- return CL_VIRUS;
- }
-
- close(ndesc);
- if(!cli_leavetemps_flag)
- unlink(tempfile);
- free(tempfile);
- } else {
- free(wwp);
- free(dest);
- cli_dbgmsg("WWPpack: Decompression failed\n");
- }
+ CLI_UNPTEMP("WWPack",(src,packer,exe_sections,0));
+ CLI_UNPRESULTS("WWPack",(wwunpack(src, ssize, packer, exe_sections, nsections-1, e_lfanew, ndesc)),0,(src,packer,0));
+ break;
}
diff -pruN clamav-0.92.1.orig/libclamav/wwunpack.c clamav-0.92.1/libclamav/wwunpack.c
--- clamav-0.92.1.orig/libclamav/wwunpack.c 2007-12-06 13:59:04.000000000 +0100
+++ clamav-0.92.1/libclamav/wwunpack.c 2008-04-24 19:37:34.000000000 +0200
@@ -1,6 +1,7 @@
/*
- * Copyright (C) 2006 Sensory Networks, Inc.
- * Written by aCaB <acab at clamav.net>
+ * Copyright (C) 2007 Sourcefire Inc.
+ * Author: aCaB <acab at clamav.net>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
@@ -16,346 +17,218 @@
* MA 02110-1301, USA.
*/
-/*
-** wwunpack.c
-**
-** 09/07/2k6 - Campioni del mondo!!!
-** 14/07/2k6 - RCE'ed + standalone sect unpacker
-** 15/07/2k6 - Merge started
-** 17/07/2k6 - Rebuild
-** 18/07/2k6 - Secured (well, hopefully...)
-**
-*/
-
-/*
-** Unpacks+rebuilds WWPack32 1.20
-**
-** Just boooooring stuff, blah.
-**
-*/
-
-
-/*
-** TODO:
-**
-** review
-** check eax vs al
-** (check for dll's)
-** (have a look at older versions)
-**
-*/
-
-
#if HAVE_CONFIG_H
#include "clamav-config.h"
#endif
-#include <stdlib.h>
-#include <string.h>
-
#include "cltypes.h"
#include "others.h"
-#include "wwunpack.h"
-
-#define VAALIGN(s) (((s)/0x1000+((s)%0x1000!=0))*0x1000)
-#define FIXVS(v, r) (VAALIGN((r>v)?r:v))
+#include "execs.h"
+#if HAVE_STRING_H
+#include <string.h>
+#endif
-static int getbitmap(uint32_t *bitmap, char **src, uint8_t *bits, char *buf, unsigned int size) {
- if (! CLI_ISCONTAINED(buf, size, *src, 4)) return 1;
- *bitmap=cli_readint32(*src);
- *src+=4;
- *bits=32;
- return 0;
+#define RESEED \
+if (CLI_ISCONTAINED(compd, szd, ccur, 4)) { \
+ bt = cli_readint32(ccur); \
+ ccur+=4; \
+} else { \
+ cli_dbgmsg("WWPack: Out of bits\n"); \
+ error=1; \
+} \
+bc = 32;
+
+
+#define BIT \
+bits = bt>>31; \
+bt<<=1; \
+if(!--bc) { \
+ RESEED; \
}
-static int getbits(uint8_t X, uint32_t *eax, uint32_t *bitmap, uint8_t *bits, char **src, char *buf, unsigned int size) {
- *eax=*bitmap>>(32-X);
- if (*bits>X) {
- *bitmap<<=X;
- *bits-=X;
- } else if (*bits<X) {
- X-=*bits;
- *eax>>=X;
- if (getbitmap(bitmap, src, bits, buf, size)) return 1;
- *eax<<=X;
- *eax|=*bitmap>>(32-X);
- *bitmap<<=X;
- *bits-=X;
- } else {
- if (getbitmap(bitmap, src, bits, buf, size)) return 1;
- }
- return 0;
+#define BITS(N) \
+bits = bt>>(32-(N)); \
+if (bc>=(N)) { \
+ bc -= (N); \
+ bt<<=(N); \
+ if (!bc) { \
+ RESEED; \
+ } \
+} else { \
+ if (CLI_ISCONTAINED(compd, szd, ccur, 4)) { \
+ bt = cli_readint32(ccur); \
+ ccur+=4; \
+ bc += 32 - (N); \
+ bits |= bt>>(bc); \
+ bt <<= (32-bc); \
+ } else { \
+ cli_dbgmsg("WWPack: Out of bits\n"); \
+ error=1; \
+ } \
}
-static int wunpsect(char *packed, char *unpacked, unsigned int psize, unsigned int usize) {
- char *src=packed, *dst=unpacked;
- uint32_t bitmap, eax;
- uint8_t bits;
- unsigned int lostbit, getmorestuff;
- uint16_t backbytes;
- uint16_t backsize;
- uint8_t oal;
-
- if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;
- eax=bitmap;
+int wwunpack(uint8_t *exe, uint32_t exesz, uint8_t *wwsect, struct cli_exe_section *sects, uint16_t scount, uint32_t pe, int desc) {
+ uint8_t *structs = wwsect + 0x2a1, *compd, *ccur, *unpd, *ucur, bc;
+ uint32_t src, srcend, szd, bt, bits;
+ int error=0, i;
+ cli_dbgmsg("in wwunpack\n");
while (1) {
- lostbit=bitmap>>31;
- bitmap<<=1;
- bits--;
- if (!lostbit && bits) {
- if (!(CLI_ISCONTAINED(packed, psize, src, 1) && CLI_ISCONTAINED(unpacked, usize, dst, 1))) return 1;
- *dst++=*src++;
- continue;
- }
-
- if (!bits) {
- if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;
- eax=bitmap;
- if (!lostbit) {
- if (!(CLI_ISCONTAINED(packed, psize, src, 1) && CLI_ISCONTAINED(unpacked, usize, dst, 1))) return 1;
- *dst++=*src++;
+ if (!CLI_ISCONTAINED(wwsect, sects[scount].rsz, structs, 17)) {
+ cli_dbgmsg("WWPack: Array of structs out of section\n");
+ break;
+ }
+ src = sects[scount].rva - cli_readint32(structs); /* src delta / dst delta - not used / dwords / end of src */
+ structs+=8;
+ szd = cli_readint32(structs) * 4;
+ structs+=4;
+ srcend = cli_readint32(structs);
+ structs+=4;
+
+ unpd = ucur = exe+src+srcend+4-szd;
+ if (!szd || !CLI_ISCONTAINED(exe, exesz, unpd, szd)) {
+ cli_dbgmsg("WWPack: Compressed data out of file\n");
+ break;
+ }
+ cli_dbgmsg("WWP: src: %x, szd: %x, srcend: %x - %x\n", src, szd, srcend, srcend+4-szd);
+ if (!(compd = cli_malloc(szd))) break;
+ memcpy(compd, unpd, szd);
+ memset(unpd, -1, szd); /*FIXME*/
+ ccur=compd;
+
+ RESEED;
+ while(!error) {
+ uint32_t backbytes, backsize;
+ uint8_t saved;
+
+ BIT;
+ if (!bits) { /* BYTE copy */
+ if(ccur-compd>=szd || !CLI_ISCONTAINED(exe, exesz, ucur, 1))
+ error=1;
+ else
+ *ucur++=*ccur++;
continue;
}
- }
-
- if (getbits(2, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
-
- if ((eax&0xff)>=3) {
- /* 50ff - two_bytes */
- uint8_t fetchbits;
-
- if (getbits(2, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
- fetchbits=(eax&0xff)+5;
- eax--;
- if ((int16_t)(eax&0xffff)<=0) {
- /* 5113 */
- backbytes=1<<fetchbits;
- backbytes=(backbytes&0xff00)|((backbytes-31)&0xff);
- } else {
- /* 511b */
- fetchbits++;
- backbytes=1<<fetchbits;
- backbytes-=0x9f;
+
+ BITS(2);
+ if(bits==3) { /* WORD backcopy */
+ uint8_t shifted, subbed = 31;
+ BITS(2);
+ shifted = bits + 5;
+ if(bits>=2) {
+ shifted++;
+ subbed += 0x80;
+ }
+ backbytes = (1<<shifted)-subbed; /* 1h, 21h, 61h, 161h */
+ BITS(shifted); /* 5, 6, 8, 9 */
+ if(error || bits == 0x1ff) break;
+ backbytes+=bits;
+ if(!CLI_ISCONTAINED(exe, exesz, ucur, 2) || !CLI_ISCONTAINED(exe, exesz, ucur-backbytes, 2)) {
+ error=1;
+ } else {
+ ucur[0]=*(ucur-backbytes);
+ ucur[1]=*(ucur-backbytes+1);
+ ucur+=2;
+ }
+ continue;
}
- /* 5125 */
- if (getbits(fetchbits, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
- if ((eax&0xffff)==0x1ff) break;
- eax&=0xffff;
- backbytes+=eax;
- if (!(CLI_ISCONTAINED(unpacked, usize, dst-backbytes, 2) && CLI_ISCONTAINED(unpacked, usize, dst, 2))) return 1;
- *dst=*(dst-backbytes);
- dst++;
- *dst=*(dst-backbytes);
- dst++;
- continue;
- }
- /* 5143 - more_backbytes */
- oal=eax&0xff;
- getmorestuff=1;
+ /* BLOCK backcopy */
+ saved = bits; /* cmp al, 1 / pushf */
-
- if (getbits(3, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
- if ((eax&0xff)<=3) {
- lostbit=0;
- if ((eax&0xff)==3) {
- /* next_bit_or_reseed */
- lostbit=bitmap>>31;
- bitmap<<=1;
- bits--;
- if (!bits) {
- if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;
+ BITS(3);
+ if (bits<6) {
+ backbytes = bits;
+ switch(bits) {
+ case 4: /* 10,11 */
+ backbytes++;
+ case 3: /* 8,9 */
+ BIT;
+ backbytes+=bits;
+ case 0: case 1: case 2: /* 5,6,7 */
+ backbytes+=5;
+ break;
+ case 5: /* 12 */
+ backbytes=12;
+ break;
}
+ BITS(backbytes);
+ bits+=(1<<backbytes)-31;
+ } else if(bits==6) {
+ BITS(0x0e);
+ bits+=0x1fe1;
+ } else {
+ BITS(0x0f);
+ bits+=0x5fe1;
}
- eax=eax+lostbit+5;
- /* jmp more_bb_commondock */
- } else { /* >3 */
- /* 5160 - more_bb_morethan3 */
- if ((eax&0xff)==4) {
- /* next_bit_or_reseed */
- lostbit=bitmap>>31;
- bitmap<<=1;
- bits--;
- if (!bits) {
- if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;
- }
- eax=eax+lostbit+6;
- /* jmp more_bb_commondock */
- } else { /* !=4 */
- eax+=7;
- if ((eax&0xff)>=0x0d) {
- getmorestuff=0; /* jmp more_bb_PASTcommondock */
- if ((eax&0xff)==0x0d) {
- /* 5179 */
- if (getbits(0x0e, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
- eax+=0x1fe1;
+
+ backbytes = bits;
+
+ /* popf / jb */
+ if (!saved) {
+ BIT;
+ if(!bits) {
+ BIT;
+ bits+=5;
+ } else {
+ BITS(3);
+ if(bits) {
+ bits+=6;
} else {
- /* 516c */
- if (getbits(0x0f, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
- eax+=0x5fe1;
+ BITS(4);
+ if(bits) {
+ bits+=13;
+ } else {
+ uint8_t cnt = 4;
+ uint16_t shifted = 0x0d;
+
+ do {
+ if(cnt==7) { cnt = 0x0e; shifted = 0; break; }
+ shifted=((shifted+2)<<1)-1;
+ BIT;
+ cnt++;
+ } while(!bits);
+ BITS(cnt);
+ bits+=shifted;
+ }
}
- /* jmp more_bb_PASTcommondock */
- } /* al >= 0d */
- } /* al != 4 */
- } /* >3 */
-
- if (getmorestuff) {
- /* 5192 - more_bb_commondock */
- uint16_t bk=(1<<(eax&0xff))-0x1f;
- if (getbits((eax&0xff), &eax, &bitmap, &bits, &src, packed, psize)) return 1;
- eax+=bk;
- }
-
- /* 51a7 - more_bb_pastcommondock */
- eax&=0xffff;
- backbytes=eax;
- backsize=3+(oal!=1);
-
- if (oal<1) { /* overrides backsize */
- /* 51bb - more_bb_again */
-
- /* next_bit_or_reseed */
- lostbit=bitmap>>31;
- bitmap<<=1;
- bits--;
- if (!bits) {
- if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;
- }
- if (!lostbit) {
- /* 51c2 */
- /* next_bit_or_reseed */
- lostbit=bitmap>>31;
- bitmap<<=1;
- bits--;
- if (!bits) {
- if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;
}
- eax=5+lostbit;
- /* jmp setsize_and_backcopy */
+ backsize = bits;
} else {
- /* 51ce - more_bb_again_and_again */
- if (getbits(3, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
- if (eax&0xff) {
- /* 51e6 */
- eax+=6;
- /* jmp setsize_and_backcopy */
- } else {
- if (getbits(4, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
- if (eax&0xff) {
- /* 51e4 */
- eax+=7+6;
- /* jmp setsize_and_backcopy */
- } else {
- /* 51ea - OMGWTF */
- uint8_t c=4;
- uint16_t d=0x0d;
-
- while ( 1 ) {
- if (c!=7){
- d+=2;
- d<<=1;
- d--;
-
- /* next_bit_or_reseed */
- lostbit=bitmap>>31;
- bitmap<<=1;
- bits--;
- if (!bits) {
- if (getbitmap(&bitmap, &src, &bits, packed, psize)) return 1;
- }
- c++;
- if (!lostbit) continue;
- if (getbits(c, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
- d+=eax&0xff;
- eax&=0xffffff00;
- eax|=d&0xff;
- } else {
- if (getbits(14, &eax, &bitmap, &bits, &src, packed, psize)) return 1;
- }
- break;
- } /* while */
- } /* OMGWTF */
- } /* eax&0xff */
- } /* lostbit */
- /* 521b - setsize_and_backcopy */
- backsize=eax&0xffff;
- }
-
- /* 521e - backcopy */
- if (!(CLI_ISCONTAINED(unpacked, usize, dst-backbytes, backsize) && CLI_ISCONTAINED(unpacked, usize, dst, backsize))) return 1;
- while(backsize--){
- *dst=*(dst-backbytes);
- dst++;
- }
-
- } /* while true */
-
- return 0;
-}
-
-int wwunpack(char *exe, uint32_t exesz, uint32_t headsize, uint32_t min, uint32_t wwprva, uint32_t e_lfanew, char *wwp, uint32_t wwpsz, uint16_t sects) {
- char *stuff=wwp+0x2a1, *packed, *unpacked;
- uint32_t rva, csize;
-
- cli_dbgmsg("in wwunpack\n");
-
+ backsize = saved+2;
+ }
- while(1) {
- if (!CLI_ISCONTAINED(wwp, wwpsz, stuff, 17)) {
- cli_dbgmsg("WWPack: next chunk out ouf file, giving up.\n");
- return 1;
- }
- if ((csize=cli_readint32(stuff+8)*4)!=(uint32_t)cli_readint32(stuff+12)+4) {
- cli_dbgmsg("WWPack: inconsistent/hacked data, go figure!\n");
- return 1;
- }
- rva = wwprva-cli_readint32(stuff);
- if((packed = (char *) cli_calloc(csize, sizeof(char))) == NULL) {
- cli_dbgmsg("WWPack: Can't allocate %d bytes\n", csize);
- return 1;
- }
- unpacked=exe+headsize+rva-min;
- if (!CLI_ISCONTAINED(exe, exesz, unpacked, csize)) {
- free(packed);
- cli_dbgmsg("WWPack: packed data out of bounds, giving up.\n");
- return 1;
+ if(!CLI_ISCONTAINED(exe, exesz, ucur, backsize) || !CLI_ISCONTAINED(exe, exesz, ucur-backbytes, backsize)) error=1;
+ while(backsize--) {
+ *ucur=*(ucur-backbytes);
+ ucur++;
+ }
}
- memcpy(packed, unpacked, csize);
- if (wunpsect(packed, unpacked, csize, exesz-(unpacked-exe))) {
- free(packed);
- cli_dbgmsg("WWPack: unpacking failed.\n");
- return 1;
+ free(compd);
+ if(error) {
+ cli_dbgmsg("WWPack: decompression error\n");
+ break;
}
- free(packed);
- if (!stuff[16]) break;
- stuff+=17;
+ if (error || !*structs++) break;
}
- stuff=exe+e_lfanew;
- stuff[6]=sects&0xff;
- stuff[7]=sects>>8;
-
- csize=cli_readint32(wwp+0x295)+wwprva+0x299;
- cli_dbgmsg("WWPack: found OEP @%x\n", csize);
- cli_writeint32(stuff+0x28, csize);
-
- csize=cli_readint32(stuff+0x50)-VAALIGN(wwpsz);
- cli_writeint32(stuff+0x50, csize);
-
-
- stuff+=0x18+(cli_readint32(stuff+0x14)&0xffff);
- while (sects--) {
- uint32_t v=cli_readint32(stuff+8);
- uint32_t r=cli_readint32(stuff+16);
- csize=FIXVS(v, r);
- cli_writeint32(stuff+8, csize);
- cli_writeint32(stuff+16, csize);
- cli_writeint32(stuff+20, cli_readint32(stuff+12)-min+headsize);
- stuff+=0x28;
+ if(!error) {
+ exe[pe+6]=(uint8_t)scount;
+ exe[pe+7]=(uint8_t)(scount>>8);
+ cli_writeint32(&exe[pe+0x28], cli_readint32(wwsect+0x295)+sects[scount].rva+0x299);
+ cli_writeint32(&exe[pe+0x50], cli_readint32(&exe[pe+0x50])-sects[scount].vsz);
+
+ structs = &exe[0xffff&cli_readint32(&exe[pe+0x14])+pe+0x18];
+ for(i=0 ; i<scount ; i++) {
+ cli_writeint32(structs+8, sects[i].vsz);
+ cli_writeint32(structs+12, sects[i].rva);
+ cli_writeint32(structs+16, sects[i].vsz);
+ cli_writeint32(structs+20, sects[i].rva);
+ structs+=0x28;
+ }
+ memset(structs, 0, 0x28);
+ error = cli_writen(desc, exe, exesz)!=exesz;
}
- memset(stuff, 0, 0x28);
-
- return 0;
+ return error;
}
diff -pruN clamav-0.92.1.orig/libclamav/wwunpack.h clamav-0.92.1/libclamav/wwunpack.h
--- clamav-0.92.1.orig/libclamav/wwunpack.h 2007-12-06 13:59:04.000000000 +0100
+++ clamav-0.92.1/libclamav/wwunpack.h 2008-04-24 19:37:34.000000000 +0200
@@ -20,8 +20,8 @@
#define __WWP32_H
#include "cltypes.h"
-#include "rebuildpe.h"
+#include "execs.h"
-int wwunpack(char *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, char *, uint32_t, uint16_t);
+int wwunpack(uint8_t *, uint32_t, uint8_t *, struct cli_exe_section *, uint16_t, uint32_t, int);
#endif
Index: clamav.spec
===================================================================
RCS file: /cvs/extras/rpms/clamav/F-7/clamav.spec,v
retrieving revision 1.65
retrieving revision 1.66
diff -u -r1.65 -r1.66
--- clamav.spec 11 Feb 2008 22:31:07 -0000 1.65
+++ clamav.spec 25 Apr 2008 10:07:32 -0000 1.66
@@ -19,7 +19,7 @@
Summary: End-user tools for the Clam Antivirus scanner
Name: clamav
Version: 0.92.1
-Release: %release_func 1
+Release: %release_func 2
License: %{?with_unrar:proprietary}%{!?with_unrar:GPLv2}
Group: Applications/File
@@ -50,6 +50,11 @@
Patch22: clamav-0.80-initoff.patch
Patch24: clamav-0.92-private.patch
Patch25: clamav-0.92-open.patch
+# security patches
+Patch26: clamav-0.92.1-CVE-2008-0314.diff
+Patch27: clamav-0.92.1-CVE-2008-1100.diff
+Patch28: clamav-0.92.1-CVE-2008-1387.diff
+Patch29: clamav-0.92.1-CVE-2008-1833.diff
BuildRoot: %_tmppath/%name-%version-%release-root
Requires: clamav-lib = %version-%release
Requires: data(clamav)
@@ -239,6 +244,10 @@
%patch22 -p1 -b .initoff
%patch24 -p1 -b .private
%patch25 -p1 -b .open
+%patch26 -p1 -b .CVE-2008-0314
+%patch27 -p1 -b .CVE-2008-1100
+%patch28 -p1 -b .CVE-2008-1387
+%patch29 -p1 -b .CVE-2008-1833
install -p -m0644 %SOURCE300 clamav-milter/
@@ -529,6 +538,13 @@
%changelog
+* Thu Apr 24 2008 Tomas Hoger <thoger at redhat.com> - 0.92.1-2
+- Security update - backport security fixes from 0.93:
+ CVE-2008-1100 (#442360): Upack Processing Buffer Overflow Vulnerability
+ CVE-2008-1387 (#442525): Endless loop / hang with crafted arj
+ CVE-2008-0314 (#442740): PeSpin Heap Overflow Vulnerability
+ CVE-2008-1833 (#442741): PE WWPack Heap Overflow Vulnerability
+
* Mon Feb 11 2008 Enrico Scholz <enrico.scholz at informatik.tu-chemnitz.de> - 0.92.1-1
- updated to 0.92.1
- Previous message (by thread): rpms/clamav/F-8 clamav-0.92.1-CVE-2008-0314.diff, NONE, 1.1 clamav-0.92.1-CVE-2008-1100.diff, NONE, 1.1 clamav-0.92.1-CVE-2008-1387.diff, NONE, 1.1 clamav-0.92.1-CVE-2008-1833.diff, NONE, 1.1 clamav.spec, 1.67, 1.68
- Next message (by thread): rpms/speex/devel speex.spec,1.24,1.25
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-extras-commits
mailing list