bb12170: Added pointer arithmetic guards to PE MEW unpacking code.

pull/51/head
Micah Snyder 7 years ago
parent a8370a7a1e
commit 20e3cfc08a
  1. 49
      libclamav/mew.c
  2. 18
      libclamav/pe.c

@ -784,18 +784,59 @@ uint32_t lzma_upack_esi_54(struct lzmastate *p, uint32_t old_eax, uint32_t *old_
return 0;
}
/**
* @brief Unpack MEW 11 packed PE file
*
* @param src buffer to unpack
* @param off offset of diff
* @param ssize pe section size
* @param dsize diff size
* @param base OPTIONAL_HEADER32.ImageBase
* @param vadd RVA of pe section
* @param uselzma Bool - use LZMA
* @param filedesc File descriptor
* @return int Returns -1 on failure, 1 on success.
*/
int unmew11(char *src, uint32_t off, uint32_t ssize, uint32_t dsize, uint32_t base, uint32_t vadd, int uselzma, int filedesc)
{
uint32_t entry_point, newedi, loc_ds=dsize, loc_ss=ssize;
char *source = src + dsize + off;
const char *lesi = source + 12;
char *source = NULL;
const char *lesi = NULL;
char *ledi;
const char *f1;
char *f2;
int i;
struct cli_exe_section *section = NULL;
uint32_t vma = base + vadd, size_sum = ssize + dsize;
uint32_t vma = base + vadd;
uint32_t size_sum = ssize + dsize;
/* Guard against integer overflows */
if (base + vadd < base) {
cli_dbgmsg("MEW: base (%08x) + PE section RVA (%08x) exceeds max size of unsigned int (%08x)\n",
base, vadd, UINT32_MAX);
return -1;
}
if (ssize + dsize < ssize) {
cli_dbgmsg("MEW: section size (%08x) + diff size (%08x) exceeds max size of unsigned int (%08x)\n",
ssize, dsize, UINT32_MAX);
return -1;
}
if (((size_t)(src + off) < (size_t)(src)) ||
((size_t)(src + off) < (size_t)(off)))
{
cli_dbgmsg("MEW: Buffer pointer (%08zx) + offset (%08zx) exceeds max size of pointer (%08lx)\n",
(size_t)src, (size_t)off, SIZE_MAX);
return -1;
}
/* Ensure that off + required data exists within buffer */
if (!CLI_ISCONTAINED(src, size_sum, src + off, 12)) {
cli_dbgmsg("MEW: Data reference exceeds size of provided buffer.\n");
return -1;
}
source = src + dsize + off;
lesi = source + 12;
entry_point = cli_readint32(source + 4);
newedi = cli_readint32(source + 8);

@ -47,6 +47,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#if HAVE_STRING_H
#include <string.h>
@ -3899,7 +3900,10 @@ int cli_scanpe(cli_ctx *ctx)
else
cli_dbgmsg("MEW: Win9x compatibility was NOT set!\n");
if((offdiff = cli_readint32(tbuff+1) - EC32(optional_hdr32.ImageBase)) <= exe_sections[i + 1].rva || offdiff >= exe_sections[i + 1].rva + exe_sections[i + 1].raw - 4) {
offdiff = cli_readint32(tbuff+1) - EC32(optional_hdr32.ImageBase);
if ((offdiff <= exe_sections[i + 1].rva) ||
(offdiff >= exe_sections[i + 1].rva + exe_sections[i + 1].raw - 4))
{
cli_dbgmsg("MEW: ESI is not in proper section\n");
break;
}
@ -3914,6 +3918,18 @@ int cli_scanpe(cli_ctx *ctx)
ssize = exe_sections[i + 1].vsz;
dsize = exe_sections[i].vsz;
/* Guard against integer overflow */
if ((ssize + dsize < ssize) || (ssize + dsize < dsize)) {
cli_dbgmsg("MEW: section size (%08x) + diff size (%08x) exceeds max size of unsigned int (%08x)\n", ssize, dsize, UINT32_MAX);
break;
}
/* Verify that offdiff does not exceed the ssize + sdiff */
if (offdiff >= ssize + dsize) {
cli_dbgmsg("MEW: offdiff (%08x) exceeds section size + diff size (%08x)\n", offdiff, ssize + dsize);
break;
}
cli_dbgmsg("MEW: ssize %08x dsize %08x offdiff: %08x\n", ssize, dsize, offdiff);
CLI_UNPSIZELIMITS("MEW", MAX(ssize, dsize));

Loading…
Cancel
Save