Skip to content

Commit

Permalink
mbr: adjusted filetype checks and changed to type 1 filetype sig
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin Lin committed Mar 13, 2014
1 parent 84acb72 commit e5d1380
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 29 deletions.
23 changes: 8 additions & 15 deletions libclamav/filetypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,21 +311,14 @@ cli_file_t cli_filetype2(fmap_t *map, const struct cl_engine *engine, cli_file_t
}
}
} else if (ret == CL_TYPE_MBR) {
const unsigned char *rbuff = buff+512;
int ri;

/* raw dmgs must be a multiple of 512 */
if ((map->len % 512) == 0 && map->len > 512) {
/* check if the MBR is a valid configuration */
if (cli_mbr_check(buff, bread, map->len) == 0) {
return CL_TYPE_MBR;
}

/* check if detected MBR is protective or hybridon GPT */
if (cli_mbr_check_gpt(buff, bread) != 0) {
cli_dbgmsg("Recognized GUID Partition Table file\n");
return CL_TYPE_GPT;
}
/* given filetype sig type 0 */
int iret = cli_mbr_check(buff, bread, map->len);
if (iret == CL_TYPE_GPT) {
cli_dbgmsg("Recognized GUID Partition Table file\n");
return CL_TYPE_GPT;
}
else if (iret == CL_CLEAN) {
return CL_TYPE_MBR;
}

/* re-detect type */
Expand Down
2 changes: 1 addition & 1 deletion libclamav/filetypes_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ static const char *ftypes_int[] = {
"4:1024:482B0004:HFS+ partition:CL_TYPE_PART_ANY:CL_TYPE_PART_HFSPLUS:75",
"4:1024:48580005:HFSX partition:CL_TYPE_PART_ANY:CL_TYPE_PART_HFSPLUS:75",
"0:0:FD377A585A00:XZ container file:CL_TYPE_ANY:CL_TYPE_XZ:75",
"0:510:55AA:Disk Image - Master Boot Record:CL_TYPE_ANY:CL_TYPE_MBR:77",
"1:510:55AA:Disk Image - Master Boot Record:CL_TYPE_ANY:CL_TYPE_MBR:77",
"0:512:4546492050415254:Disk Image - GUID Partition Table:CL_TYPE_ANY:CL_TYPE_GPT:77",
"1:0:4552{510}504D0000:Disk Image - Apple Partition Map:CL_TYPE_ANY:CL_TYPE_APM:77",
NULL
Expand Down
49 changes: 39 additions & 10 deletions libclamav/mbr.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,26 +89,49 @@ int cli_mbr_check(const unsigned char *buff, size_t len, size_t maplen) {
memcpy(&mbr, buff+mbr_base, sizeof(mbr));
mbr_convert_to_host(&mbr);

//mbr_printbr(&mbr);
if ((mbr.entries[0].type == MBR_PROTECTIVE) || (mbr.entries[0].type == MBR_HYBRID))
return CL_TYPE_GPT;

return mbr_check_mbr(&mbr, maplen, sectorsize);
}

int cli_mbr_check_gpt(const unsigned char *buff, size_t len) {
int cli_mbr_check2(cli_ctx *ctx, size_t sectorsize) {
struct mbr_boot_record mbr;
off_t mbr_base = 0;
size_t sectorsize = 512;
off_t pos = 0, mbr_base = 0;
size_t maplen;

if (len < sectorsize) {
return CL_EFORMAT;
if (!ctx || !ctx->fmap) {
cli_errmsg("cli_scanmbr: Invalid context\n");
return CL_ENULLARG;
}

/* sector size calculation, actual value is OS dependent */
if (sectorsize == 0)
sectorsize = MBR_SECTOR_SIZE;

mbr_base = sectorsize - sizeof(struct mbr_boot_record);
memcpy(&mbr, buff+mbr_base, sizeof(mbr));
mbr_convert_to_host(&mbr);

return ((mbr.entries[0].type == MBR_PROTECTIVE) ||
(mbr.entries[0].type == MBR_HYBRID));
/* size of total file must be a multiple of the sector size */
maplen = (*ctx->fmap)->real_len;
if ((maplen % sectorsize) != 0) {
cli_dbgmsg("cli_scanmbr: File sized %u is not a multiple of sector size %u\n",
maplen, sectorsize);
return CL_EFORMAT;
}

/* sector 0 (first sector) is the master boot record */
pos = (MBR_SECTOR * sectorsize) + mbr_base;

/* read the master boot record */
if (fmap_readn(*ctx->fmap, &mbr, pos, sizeof(mbr)) != sizeof(mbr)) {
cli_dbgmsg("cli_scanmbr: Invalid master boot record\n");
return CL_EFORMAT;
}

if ((mbr.entries[0].type == MBR_PROTECTIVE) || (mbr.entries[0].type == MBR_HYBRID))
return CL_TYPE_GPT;

return mbr_check_mbr(&mbr, maplen, sectorsize);
}

/* sets sectorsize to default value if specfied to be 0 */
Expand Down Expand Up @@ -448,6 +471,12 @@ static int mbr_check_mbr(struct mbr_boot_record *record, size_t maplen, size_t s
return CL_EFORMAT;
}

/* check the maplen */
if ((maplen / sectorsize) < 2) {
cli_dbgmsg("cli_scanmbr: file is too small to hold disk image\n");
return CL_EFORMAT;
}

return CL_CLEAN;
}

Expand Down
2 changes: 1 addition & 1 deletion libclamav/mbr.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ struct mbr_boot_record {
#endif

int cli_mbr_check(const unsigned char *buff, size_t len, size_t maplen);
int cli_mbr_check_gpt(const unsigned char *buff, size_t len);
int cli_mbr_check2(cli_ctx *ctx, size_t sectorsize);
int cli_scanmbr(cli_ctx *ctx, size_t sectorsize);
void mbr_convert_to_host(struct mbr_boot_record *record);

Expand Down
21 changes: 19 additions & 2 deletions libclamav/scanners.c
Original file line number Diff line number Diff line change
Expand Up @@ -2280,6 +2280,23 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_
}
break;

case CL_TYPE_MBR:
{
int iret = cli_mbr_check2(ctx, 0);
if (iret == CL_TYPE_GPT) {
cli_dbgmsg("Recognized GUID Partition Table file\n");
ctx->container_type = CL_TYPE_GPT;
nret = cli_scangpt(ctx, 0);
cli_dbgmsg("GPT signature found at %u\n", (unsigned int) fpt->offset);
}
else if (iret == CL_CLEAN) {
ctx->container_type = CL_TYPE_MBR;
nret = cli_scanmbr(ctx, 0);
cli_dbgmsg("MBR signature found at %u\n", (unsigned int) fpt->offset);
}
}
break;

case CL_TYPE_PDF:
if(type != CL_TYPE_PDF && SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF)) {
ctx->container_type = CL_TYPE_PDF;
Expand Down Expand Up @@ -3137,8 +3154,8 @@ int cli_map_scandesc(cl_fmap_t *map, off_t offset, size_t length, cli_ctx *ctx,
long long len1, len2;
len1 = old_off + old_len;
len2 = map->nested_offset + map->len;
cli_warnmsg("internal map error: %ld, %lld; %ld, %lld\n", old_off,
len1, map->offset, len2);
cli_warnmsg("internal map error: %lu, %llu; %lu, %llu\n", (long unsigned)old_off,
(long long unsigned)len1, (long unsigned)map->offset, (long long unsigned)len2);
}

ctx->fmap--;
Expand Down

0 comments on commit e5d1380

Please sign in to comment.