diff --git a/libclamav/bytecode_api.c b/libclamav/bytecode_api.c index 987c8220a..bd8e4b166 100644 --- a/libclamav/bytecode_api.c +++ b/libclamav/bytecode_api.c @@ -453,18 +453,57 @@ int32_t cli_bcapi_read_number(struct cli_bc_ctx *ctx, uint32_t radix) int32_t cli_bcapi_hashset_new(struct cli_bc_ctx *ctx ) { + unsigned n = ctx->nhashsets+1; + struct cli_hashset *s = cli_realloc(ctx->hashsets, sizeof(*ctx->hashsets)*n); + if (!s) + return -1; + ctx->hashsets = s; + ctx->nhashsets = n; + s = &s[n-1]; + cli_hashset_init(s, 16, 80); + return n-1; +} + +static struct cli_hashset *get_hashset(struct cli_bc_ctx *ctx, int32_t id) +{ + if (id < 0 || id >= ctx->nhashsets || !ctx->hashsets) + return NULL; + return &ctx->hashsets[id]; } + int32_t cli_bcapi_hashset_add(struct cli_bc_ctx *ctx , int32_t id, uint32_t key) { + struct cli_hashset *s = get_hashset(ctx, id); + if (!s) + return -1; + return cli_hashset_addkey(s, key); } + int32_t cli_bcapi_hashset_remove(struct cli_bc_ctx *ctx , int32_t id, uint32_t key) { + struct cli_hashset *s = get_hashset(ctx, id); + if (!s) + return -1; +// return cli_hashset_removekey(s, key); } + int32_t cli_bcapi_hashset_contains(struct cli_bc_ctx *ctx , int32_t id, uint32_t key) { + struct cli_hashset *s = get_hashset(ctx, id); + if (!s) + return 0; + return cli_hashset_contains(s, key); +} + +int32_t cli_bcapi_hashset_empty(struct cli_bc_ctx *ctx, int32_t id) +{ + struct cli_hashset *s = get_hashset(ctx, id); + return !s->count; } + int32_t cli_bcapi_hashset_done(struct cli_bc_ctx *ctx , int32_t id) { + /* TODO */ } int32_t cli_bcapi_buffer_pipe_new(struct cli_bc_ctx *ctx, uint32_t size) @@ -503,21 +542,24 @@ int32_t cli_bcapi_buffer_pipe_new_fromfile(struct cli_bc_ctx *ctx , uint32_t at) if (!b) { return -1; } - b = &b[n-1]; ctx->buffers = b; ctx->nbuffers = n; + b = &b[n-1]; /* NULL data means read from file at pos read_cursor */ b->data = NULL; b->size = 0; b->read_cursor = at; b->write_cursor = 0; + return n-1; } static struct bc_buffer *get_buffer(struct cli_bc_ctx *ctx, int32_t id) { - if (!ctx->buffers || id < 0 || id >= ctx->nbuffers) + if (!ctx->buffers || id < 0 || id >= ctx->nbuffers) { + cli_dbgmsg("bytecode api: invalid buffer id %u\n", id); return NULL; + } return &ctx->buffers[id]; } @@ -614,8 +656,10 @@ int32_t cli_bcapi_inflate_init(struct cli_bc_ctx *ctx, int32_t from, int32_t to, z_stream stream; struct bc_inflate *b; unsigned n = ctx->ninflates + 1; - if (!get_buffer(ctx, from) || !get_buffer(ctx, to)) + if (!get_buffer(ctx, from) || !get_buffer(ctx, to)) { + cli_dbgmsg("bytecode api: inflate_init: invalid buffers!\n"); return -1; + } memset(&stream, 0, sizeof(stream)); ret = inflateInit2(&stream, windowBits); switch (ret) { @@ -663,7 +707,7 @@ int32_t cli_bcapi_inflate_process(struct cli_bc_ctx *ctx , int32_t id) int ret; unsigned avail_in_orig, avail_out_orig; struct bc_inflate *b = get_inflate(ctx, id); - if (!b) + if (!b || b->from == -1 || b->to == -1) return -1; b->stream.avail_in = avail_in_orig = @@ -685,7 +729,7 @@ int32_t cli_bcapi_inflate_process(struct cli_bc_ctx *ctx , int32_t id) if (!b->needSync) { ret = inflate(&b->stream, Z_NO_FLUSH); if (ret == Z_DATA_ERROR) { - cli_dbgmsg("bytecode api: inflate at %u: %s\n", b->stream.total_in, + cli_dbgmsg("bytecode api: inflate at %u: %s, trying to recover\n", b->stream.total_in, b->stream.msg); b->needSync = 1; } @@ -693,6 +737,7 @@ int32_t cli_bcapi_inflate_process(struct cli_bc_ctx *ctx , int32_t id) if (b->needSync) { ret = inflateSync(&b->stream); if (ret == Z_OK) { + cli_dbgmsg("bytecode api: successfully recovered inflate stream\n"); b->needSync = 0; continue; } diff --git a/libclamav/bytecode_api.h b/libclamav/bytecode_api.h index 3c04ce6d5..1a942027b 100644 --- a/libclamav/bytecode_api.h +++ b/libclamav/bytecode_api.h @@ -229,6 +229,7 @@ int32_t hashset_add(int32_t hs, uint32_t key); int32_t hashset_remove(int32_t hs, uint32_t key); int32_t hashset_contains(int32_t hs, uint32_t key); int32_t hashset_done(int32_t id); +int32_t hashset_empty(int32_t id); int32_t buffer_pipe_new(uint32_t size); int32_t buffer_pipe_new_fromfile(uint32_t pos); diff --git a/libclamav/bytecode_api_decl.c b/libclamav/bytecode_api_decl.c index a53bad900..839003e78 100644 --- a/libclamav/bytecode_api_decl.c +++ b/libclamav/bytecode_api_decl.c @@ -61,6 +61,7 @@ int32_t cli_bcapi_hashset_add(struct cli_bc_ctx *ctx , int32_t, uint32_t); int32_t cli_bcapi_hashset_remove(struct cli_bc_ctx *ctx , int32_t, uint32_t); int32_t cli_bcapi_hashset_contains(struct cli_bc_ctx *ctx , int32_t, uint32_t); int32_t cli_bcapi_hashset_done(struct cli_bc_ctx *ctx , int32_t); +int32_t cli_bcapi_hashset_empty(struct cli_bc_ctx *ctx , int32_t); int32_t cli_bcapi_buffer_pipe_new(struct cli_bc_ctx *ctx , uint32_t); int32_t cli_bcapi_buffer_pipe_new_fromfile(struct cli_bc_ctx *ctx , uint32_t); uint32_t cli_bcapi_buffer_pipe_read_avail(struct cli_bc_ctx *ctx , int32_t); @@ -172,18 +173,19 @@ const struct cli_apicall cli_apicalls[]={ {"hashset_remove", 10, 3, 0}, {"hashset_contains", 10, 4, 0}, {"hashset_done", 8, 6, 2}, - {"buffer_pipe_new", 8, 7, 2}, - {"buffer_pipe_new_fromfile", 8, 8, 2}, - {"buffer_pipe_read_avail", 8, 9, 2}, + {"hashset_empty", 8, 7, 2}, + {"buffer_pipe_new", 8, 8, 2}, + {"buffer_pipe_new_fromfile", 8, 9, 2}, + {"buffer_pipe_read_avail", 8, 10, 2}, {"buffer_pipe_read_get", 11, 0, 6}, {"buffer_pipe_read_stopped", 10, 5, 0}, - {"buffer_pipe_write_avail", 8, 10, 2}, + {"buffer_pipe_write_avail", 8, 11, 2}, {"buffer_pipe_write_get", 11, 1, 6}, {"buffer_pipe_write_stopped", 10, 6, 0}, - {"buffer_pipe_done", 8, 11, 2}, + {"buffer_pipe_done", 8, 12, 2}, {"inflate_init", 9, 0, 7}, - {"inflate_process", 8, 12, 2}, - {"inflate_done", 8, 13, 2} + {"inflate_process", 8, 13, 2}, + {"inflate_done", 8, 14, 2} /* Bytecode APIcalls END */ }; const cli_apicall_int2 cli_apicalls0[] = { @@ -218,6 +220,7 @@ const cli_apicall_int1 cli_apicalls2[] = { (cli_apicall_int1)cli_bcapi_extract_new, (cli_apicall_int1)cli_bcapi_read_number, (cli_apicall_int1)cli_bcapi_hashset_done, + (cli_apicall_int1)cli_bcapi_hashset_empty, (cli_apicall_int1)cli_bcapi_buffer_pipe_new, (cli_apicall_int1)cli_bcapi_buffer_pipe_new_fromfile, (cli_apicall_int1)cli_bcapi_buffer_pipe_read_avail, diff --git a/libclamav/bytecode_api_impl.h b/libclamav/bytecode_api_impl.h index 55ce68bbb..ce9c3c9b0 100644 --- a/libclamav/bytecode_api_impl.h +++ b/libclamav/bytecode_api_impl.h @@ -58,6 +58,7 @@ int32_t cli_bcapi_hashset_add(struct cli_bc_ctx *ctx , int32_t, uint32_t); int32_t cli_bcapi_hashset_remove(struct cli_bc_ctx *ctx , int32_t, uint32_t); int32_t cli_bcapi_hashset_contains(struct cli_bc_ctx *ctx , int32_t, uint32_t); int32_t cli_bcapi_hashset_done(struct cli_bc_ctx *ctx , int32_t); +int32_t cli_bcapi_hashset_empty(struct cli_bc_ctx *ctx , int32_t); int32_t cli_bcapi_buffer_pipe_new(struct cli_bc_ctx *ctx , uint32_t); int32_t cli_bcapi_buffer_pipe_new_fromfile(struct cli_bc_ctx *ctx , uint32_t); uint32_t cli_bcapi_buffer_pipe_read_avail(struct cli_bc_ctx *ctx , int32_t); diff --git a/libclamav/bytecode_priv.h b/libclamav/bytecode_priv.h index 2d3ad260f..c5b6ea8f8 100644 --- a/libclamav/bytecode_priv.h +++ b/libclamav/bytecode_priv.h @@ -30,6 +30,7 @@ #include "bytecode_hooks.h" #include "fmap.h" #include "mpool.h" +#include "hashtab.h" typedef uint32_t operand_t; typedef uint16_t bbid_t; @@ -171,6 +172,8 @@ struct cli_bc_ctx { unsigned ninflates; struct bc_buffer *buffers; unsigned nbuffers; + struct cli_hashset *hashsets; + unsigned nhashsets; }; struct cli_all_bc; int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct cli_bc_func *func, const struct cli_bc_inst *inst); diff --git a/libclamav/pdf.c b/libclamav/pdf.c index 7dbec76f5..1b84bdb20 100644 --- a/libclamav/pdf.c +++ b/libclamav/pdf.c @@ -75,7 +75,6 @@ cli_pdf(const char *dir, cli_ctx *ctx, off_t offset) int opt_failed = 0; cli_dbgmsg("in cli_pdf(%s)\n", dir); - size = map->len - offset; if(size <= 7) /* doesn't even include the file header */