fuzz-22348 null deref in egg utf8 conversion

Corrected memory leaks and a null dereference in the egg utf8 conversion.
pull/125/head
Andy Ragusa (aragusa) 5 years ago committed by Micah Snyder (micasnyd)
parent 8081a6b06c
commit 2049078622
  1. 16
      libclamav/blob.c
  2. 55
      libclamav/entconv.c
  3. 27
      libclamav/vba_extract.c

@ -176,7 +176,7 @@ blobGetFilename(const blob *b)
int blobAddData(blob *b, const unsigned char *data, size_t len)
{
#if HAVE_CLI_GETPAGESIZE
static int pagesize;
static int pagesize = 0;
int growth;
#endif
@ -225,6 +225,10 @@ int blobAddData(blob *b, const unsigned char *data, size_t len)
b->size = growth;
b->data = cli_malloc(growth);
if (NULL == b->data){
b->size = 0;
return -1;
}
} else if (b->size < b->len + (off_t)len) {
unsigned char *p = cli_realloc(b->data, b->size + growth);
@ -241,6 +245,10 @@ int blobAddData(blob *b, const unsigned char *data, size_t len)
b->size = (off_t)len * 4;
b->data = cli_malloc(b->size);
if (NULL == b->data){
b->size = 0;
return -1;
}
} else if (b->size < b->len + (off_t)len) {
unsigned char *p = cli_realloc(b->data, b->size + (len * 4));
@ -255,6 +263,9 @@ int blobAddData(blob *b, const unsigned char *data, size_t len)
if (b->data) {
memcpy(&b->data[b->len], data, len);
b->len += (off_t)len;
} else {
b->size = 0;
return -1;
}
return 0;
}
@ -309,8 +320,9 @@ void blobClose(blob *b)
} else {
unsigned char *ptr = cli_realloc(b->data, b->len);
if (ptr == NULL)
if (ptr == NULL) {
return;
}
cli_dbgmsg("blobClose: recovered %lu bytes from %lu\n",
(unsigned long)(b->size - b->len),

@ -787,7 +787,7 @@ cl_error_t cli_codepage_to_utf8(char* in, size_t in_size, uint16_t codepage, cha
#endif
if (NULL == in || in_size == 0 || NULL == out || NULL == out_size) {
cli_dbgmsg("egg_filename_to_utf8: Invalid args.\n");
cli_dbgmsg("cli_codepage_to_utf8: Invalid args.\n");
status = CL_EARG;
goto done;
}
@ -804,7 +804,7 @@ cl_error_t cli_codepage_to_utf8(char* in, size_t in_size, uint16_t codepage, cha
out_utf8_size = in_size;
out_utf8 = cli_calloc(1, out_utf8_size + 1);
if (NULL == out_utf8) {
cli_errmsg("egg_filename_to_utf8: Failure allocating buffer for utf8 filename.\n");
cli_errmsg("cli_codepage_to_utf8: Failure allocating buffer for utf8 filename.\n");
status = CL_EMEM;
goto done;
}
@ -829,7 +829,7 @@ cl_error_t cli_codepage_to_utf8(char* in, size_t in_size, uint16_t codepage, cha
}
if (byte_count != sigbit_count) {
cli_dbgmsg("egg_filename_to_utf8: cleaning out %d bytes from incomplete "
cli_dbgmsg("cli_codepage_to_utf8: cleaning out %d bytes from incomplete "
"utf-8 character length %d\n",
byte_count, sigbit_count);
for (; byte_count > 0; byte_count--, track++) {
@ -859,14 +859,14 @@ cl_error_t cli_codepage_to_utf8(char* in, size_t in_size, uint16_t codepage, cha
NULL,
0);
if (0 == cchWideChar) {
cli_dbgmsg("egg_filename_to_utf8: failed to determine string size needed for ansi to widechar conversion.\n");
cli_dbgmsg("cli_codepage_to_utf8: failed to determine string size needed for ansi to widechar conversion.\n");
status = CL_EPARSE;
goto done;
}
lpWideCharStr = malloc((cchWideChar + 1) * sizeof(WCHAR));
lpWideCharStr = cli_malloc((cchWideChar + 1) * sizeof(WCHAR));
if (NULL == lpWideCharStr) {
cli_dbgmsg("egg_filename_to_utf8: failed to allocate memory for wide char string.\n");
cli_dbgmsg("cli_codepage_to_utf8: failed to allocate memory for wide char string.\n");
status = CL_EMEM;
goto done;
}
@ -879,7 +879,7 @@ cl_error_t cli_codepage_to_utf8(char* in, size_t in_size, uint16_t codepage, cha
lpWideCharStr,
cchWideChar + 1);
if (0 == cchWideChar) {
cli_dbgmsg("egg_filename_to_utf8: failed to convert multibyte string to widechars.\n");
cli_dbgmsg("cli_codepage_to_utf8: failed to convert multibyte string to widechars.\n");
status = CL_EPARSE;
goto done;
}
@ -901,14 +901,14 @@ cl_error_t cli_codepage_to_utf8(char* in, size_t in_size, uint16_t codepage, cha
NULL,
NULL);
if (0 == out_utf8_size) {
cli_dbgmsg("egg_filename_to_utf8: failed to determine string size needed for widechar conversion.\n");
cli_dbgmsg("cli_codepage_to_utf8: failed to determine string size needed for widechar conversion.\n");
status = CL_EPARSE;
goto done;
}
out_utf8 = malloc(out_utf8_size + 1);
out_utf8 = cli_malloc(out_utf8_size + 1);
if (NULL == lpWideCharStr) {
cli_dbgmsg("egg_filename_to_utf8: failed to allocate memory for wide char to utf-8 string.\n");
cli_dbgmsg("cli_codepage_to_utf8: failed to allocate memory for wide char to utf-8 string.\n");
status = CL_EMEM;
goto done;
}
@ -923,7 +923,7 @@ cl_error_t cli_codepage_to_utf8(char* in, size_t in_size, uint16_t codepage, cha
NULL,
NULL);
if (0 == out_utf8_size) {
cli_dbgmsg("egg_filename_to_utf8: failed to convert widechar string to utf-8.\n");
cli_dbgmsg("cli_codepage_to_utf8: failed to convert widechar string to utf-8.\n");
status = CL_EPARSE;
goto done;
}
@ -943,9 +943,18 @@ cl_error_t cli_codepage_to_utf8(char* in, size_t in_size, uint16_t codepage, cha
}
}
if (NULL == encoding){
cli_dbgmsg("cli_codepage_to_utf8: Invalid codepage parameter passed in.\n");
goto done;
}
for (attempt = 1; attempt <= 3; attempt++) {
char* out_utf8_tmp;
char* out_utf8_index;
char * inbuf = in;
size_t inbufsize = inbytesleft;
size_t iconvRet = -1;
char* out_utf8_tmp = NULL;
char* out_utf8_index = NULL;
/* Charset to UTF-8 should never exceed in_size * 6;
* We can shrink final buffer after the conversion, if needed. */
@ -956,32 +965,36 @@ cl_error_t cli_codepage_to_utf8(char* in, size_t in_size, uint16_t codepage, cha
out_utf8 = cli_calloc(1, out_utf8_size + 1);
if (NULL == out_utf8) {
cli_errmsg("egg_filename_to_utf8: Failure allocating buffer for utf8 data.\n");
cli_errmsg("cli_codepage_to_utf8: Failure allocating buffer for utf8 data.\n");
status = CL_EMEM;
goto done;
}
out_utf8_index = out_utf8;
conv = iconv_open("UTF-8//TRANSLIT", encoding);
if (conv == (iconv_t)-1) {
cli_warnmsg("egg_filename_to_utf8: Failed to open iconv.\n");
cli_warnmsg("cli_codepage_to_utf8: Failed to open iconv.\n");
goto done;
}
if ((size_t)-1 == iconv(conv, &in, &inbytesleft, &out_utf8_index, &outbytesleft)) {
iconvRet = iconv(conv, &inbuf, &inbufsize, &out_utf8_index, &outbytesleft);
iconv_close(conv);
conv = (iconv_t) -1;
if ((size_t)-1 == iconvRet){
switch (errno) {
case E2BIG:
cli_warnmsg("egg_filename_to_utf8: iconv error: There is not sufficient room at *outbuf.\n");
cli_warnmsg("cli_codepage_to_utf8: iconv error: There is not sufficient room at *outbuf.\n");
free(out_utf8);
out_utf8 = NULL;
continue; /* Try again, with a larger buffer. */
case EILSEQ:
cli_warnmsg("egg_filename_to_utf8: iconv error: An invalid multibyte sequence has been encountered in the input.\n");
cli_warnmsg("cli_codepage_to_utf8: iconv error: An invalid multibyte sequence has been encountered in the input.\n");
break;
case EINVAL:
cli_warnmsg("egg_filename_to_utf8: iconv error: An incomplete multibyte sequence has been encountered in the input.\n");
cli_warnmsg("cli_codepage_to_utf8: iconv error: An incomplete multibyte sequence has been encountered in the input.\n");
break;
default:
cli_warnmsg("egg_filename_to_utf8: iconv error: Unexpected error code %d.\n", errno);
cli_warnmsg("cli_codepage_to_utf8: iconv error: Unexpected error code %d.\n", errno);
}
status = CL_EPARSE;
goto done;
@ -990,7 +1003,7 @@ cl_error_t cli_codepage_to_utf8(char* in, size_t in_size, uint16_t codepage, cha
/* iconv succeeded, but probably didn't use the whole buffer. Free up the extra memory. */
out_utf8_tmp = cli_realloc(out_utf8, out_utf8_size - outbytesleft + 1);
if (NULL == out_utf8_tmp) {
cli_errmsg("egg_filename_to_utf8: failure cli_realloc'ing converted filename.\n");
cli_errmsg("cli_codepage_to_utf8: failure cli_realloc'ing converted filename.\n");
status = CL_EMEM;
goto done;
}

@ -374,6 +374,10 @@ cl_error_t
char *tempfile = NULL;
uint16_t codepage = CODEPAGE_ISO8859_1;
unsigned i;
char *mbcs_name = NULL, *utf16_name = NULL;
size_t mbcs_name_size = 0, utf16_name_size = 0;
unsigned char *module_data = NULL, *module_data_utf8 = NULL;
size_t module_data_size = 0, module_data_utf8_size = 0;
if (dir == NULL || hash == NULL || tempfd == NULL) {
return CL_EARG;
@ -773,8 +777,6 @@ cl_error_t
}
//MS-OVBA 2.3.4.2.3.2 MODULE record
case 0x0019: {
char *mbcs_name = NULL, *utf16_name = NULL;
size_t mbcs_name_size, utf16_name_size;
//MS-OVBA 2.3.4.2.3.2.1 MODULENAME
CLI_WRITEN("\n\nREM MODULENAME: ", 18);
@ -1136,9 +1138,6 @@ cl_error_t
continue;
}
unsigned char *module_data, *module_data_utf8 = NULL;
size_t module_data_size = 0, module_data_utf8_size;
module_data = cli_vba_inflate(module_fd, module_offset, &module_data_size);
if (!module_data) {
cli_dbgmsg("cli_vba_readdir_new: Failed to extract module data\n");
@ -1186,6 +1185,8 @@ cl_error_t
#undef CLI_WRITEN
#undef CLI_WRITENHEX
#undef CLI_WRITEN_MBCS
#undef CLI_WRITEN_UTF16LE
done:
if (fd >= 0) {
@ -1204,6 +1205,22 @@ done:
close(*tempfd);
*tempfd = -1;
}
if (utf16_name) {
free(utf16_name);
utf16_name = NULL;
}
if (mbcs_name) {
free(mbcs_name);
mbcs_name = NULL;
}
if (module_data){
free(module_data);
module_data = NULL;
}
if (module_data_utf8){
free(module_data_utf8);
module_data_utf8 = NULL;
}
return ret;
}

Loading…
Cancel
Save