/* * Returns the value, or -1 for failure */ int tableInsert(table_t *table, const char *key, int value) { const int v = tableFind(table, key); if(v > 0) /* duplicate key */ return (v == value) ? value : -1; /* allow real dups */ assert(value != -1); /* that would confuse us */ if(table->tableHead == NULL) table->tableLast = table->tableHead = (tableEntry *)cli_malloc(sizeof(tableEntry)); else table->tableLast = table->tableLast->next = (tableEntry *)cli_malloc(sizeof(tableEntry)); if(table->tableLast == NULL) return -1; table->tableLast->next = NULL; table->tableLast->key = strdup(key); table->tableLast->value = value; return value; }
int cli_LzmaInitUPX(CLI_LZMA **Lp, uint32_t dictsz) { CLI_LZMA *L = *Lp; if(!L) { *Lp = L = cli_calloc(sizeof(*L), 1); if(!L) { return LZMA_RESULT_DATA_ERROR; } } L->state.Properties.pb = 2; /* FIXME: these */ L->state.Properties.lp = 0; /* values may */ L->state.Properties.lc = 3; /* not be static */ L->state.Properties.DictionarySize = dictsz; if (!(L->state.Probs = (CProb *)cli_malloc(LzmaGetNumProbs(&L->state.Properties) * sizeof(CProb)))) return LZMA_RESULT_DATA_ERROR; if (!(L->state.Dictionary = (unsigned char *)cli_malloc(L->state.Properties.DictionarySize))) { free(L->state.Probs); return LZMA_RESULT_DATA_ERROR; } L->initted = 1; LzmaDecoderInit(&L->state); return LZMA_RESULT_OK; }
/* Clone the current object */ static text * textCopy(const text *t_head) { text *first = NULL, *last = NULL; while(t_head) { if(first == NULL) last = first = (text *)cli_malloc(sizeof(text)); else { last->t_next = (text *)cli_malloc(sizeof(text)); last = last->t_next; } if(last == NULL) { cli_errmsg("textCopy: Unable to allocate memory to clone object\n"); if(first) textDestroy(first); return NULL; } if(t_head->t_line) last->t_line = lineLink(t_head->t_line); else last->t_line = NULL; t_head = t_head->t_next; } if(first) last->t_next = NULL; return first; }
/* * Put the contents of the given text at the end of the current object. * The given text emptied; it can be used again if needed, though be warned that * it will have an empty line at the start. */ text * textMove(text *t_head, text *t) { text *ret; if(t_head == NULL) { if(t == NULL) { cli_errmsg("textMove fails sanity check\n"); return NULL; } t_head = (text *)cli_malloc(sizeof(text)); if(t_head == NULL) { cli_errmsg("textMove: Unable to allocate memory for head\n"); return NULL; } t_head->t_line = t->t_line; t_head->t_next = t->t_next; t->t_line = NULL; t->t_next = NULL; return t_head; } if(t == NULL) return t_head; ret = t_head; while(t_head->t_next) t_head = t_head->t_next; /* * Move the first line manually so that the caller is left clean but * empty, the rest is moved by a simple pointer reassignment */ t_head->t_next = (text *)cli_malloc(sizeof(text)); if(t_head->t_next == NULL) { cli_errmsg("textMove: Unable to allocate memory for head->next\n"); return NULL; } t_head = t_head->t_next; assert(t_head != NULL); if(t->t_line) { t_head->t_line = t->t_line; t->t_line = NULL; } else t_head->t_line = NULL; t_head->t_next = t->t_next; t->t_next = NULL; return ret; }
int cli_bm_initoff(const struct cli_matcher *root, struct cli_bm_off *data, const struct cli_target_info *info) { int ret; unsigned int i; struct cli_bm_patt *patt; if(!root->bm_patterns) { data->offtab = data->offset = NULL; data->cnt = data->pos = 0; return CL_SUCCESS; } data->cnt = data->pos = 0; data->offtab = (uint32_t *) cli_malloc(root->bm_patterns * sizeof(uint32_t)); if(!data->offtab) { cli_errmsg("cli_bm_initoff: Can't allocate memory for data->offtab\n"); return CL_EMEM; } data->offset = (uint32_t *) cli_malloc(root->bm_patterns * sizeof(uint32_t)); if(!data->offset) { cli_errmsg("cli_bm_initoff: Can't allocate memory for data->offset\n"); free(data->offtab); return CL_EMEM; } for(i = 0; i < root->bm_patterns; i++) { patt = root->bm_pattab[i]; if(patt->offdata[0] == CLI_OFF_ABSOLUTE) { data->offtab[data->cnt] = patt->offset_min + patt->prefix_length; if(data->offtab[data->cnt] >= info->fsize) continue; data->cnt++; } else if((ret = cli_caloff(NULL, info, root->type, patt->offdata, &data->offset[patt->offset_min], NULL))) { cli_errmsg("cli_bm_initoff: Can't calculate relative offset in signature for %s\n", patt->virname); free(data->offtab); free(data->offset); return ret; } else if((data->offset[patt->offset_min] != CLI_OFF_NONE) && (data->offset[patt->offset_min] + patt->length <= info->fsize)) { if(!data->cnt || (data->offset[patt->offset_min] + patt->prefix_length != data->offtab[data->cnt - 1])) { data->offtab[data->cnt] = data->offset[patt->offset_min] + patt->prefix_length; if(data->offtab[data->cnt] >= info->fsize) continue; data->cnt++; } } } cli_qsort(data->offtab, data->cnt, sizeof(uint32_t), NULL); return CL_SUCCESS; }
cli_ctx *convenience_ctx(int fd) { cli_ctx *ctx; struct cl_engine *engine; ctx = malloc(sizeof(*ctx)); if(!ctx){ printf("ctx malloc failed\n"); return NULL; } ctx->engine = engine = cl_engine_new(); if(!(ctx->engine)){ printf("engine malloc failed\n"); free(ctx); return NULL; } ctx->fmap = cli_malloc(sizeof(struct F_MAP *)); if(!(ctx->fmap)){ printf("fmap malloc failed\n"); free(engine); free(ctx); return NULL; } if(!(*ctx->fmap = fmap(fd, 0, 0))){ printf("fmap failed\n"); free(ctx->fmap); free(engine); free(ctx); return NULL; } return ctx; }
/* * Return clamav return code */ int blobGrow(blob *b, size_t len) { assert(b != NULL); assert(b->magic == BLOBCLASS); if(len == 0) return CL_SUCCESS; if(b->isClosed) { /* * Should be cli_dbgmsg, but I want to see them for now, * and cli_dbgmsg doesn't support debug levels */ cli_warnmsg("Growing closed blob\n"); b->isClosed = 0; } if(b->data == NULL) { assert(b->len == 0); assert(b->size == 0); b->data = cli_malloc(len); if(b->data) b->size = (off_t)len; } else { unsigned char *ptr = cli_realloc(b->data, b->size + len); if(ptr) { b->size += (off_t)len; b->data = ptr; } } return (b->data) ? CL_SUCCESS : CL_EMEM; }
void diff_file_mem(int fd, const char *ref, size_t len) { char c1,c2; size_t p, reflen = len; char *buf = cli_malloc(len); fail_unless_fmt(!!buf, "unable to malloc buffer: %d", len); p = read(fd, buf, len); fail_unless_fmt(p == len, "file is smaller: %lu, expected: %lu", p, len); p = 0; while(len > 0) { c1 = ref[p]; c2 = buf[p]; if(c1 != c2) break; p++; len--; } if (len > 0) fail_unless_fmt(c1 == c2, "file contents mismatch at byte: %lu, was: %c, expected: %c", p, c2, c1); free(buf); p = lseek(fd, 0, SEEK_END); fail_unless_fmt(p == reflen, "trailing garbage, file size: %ld, expected: %ld", p, reflen); close(fd); }
/* * Returns the value, or -1 for failure */ int tableInsert(table_t *table, const char *key, int value) { const int v = tableFind(table, key); if(v > 0) /* duplicate key */ return (v == value) ? value : -1; /* allow real dups */ assert(value != -1); /* that would confuse us */ if(table->tableHead == NULL) table->tableLast = table->tableHead = (tableEntry *)cli_malloc(sizeof(tableEntry)); else { /* * Re-use deleted items */ if(table->flags&TABLE_HAS_DELETED_ENTRIES) { tableEntry *tableItem; assert(table->tableHead != NULL); for(tableItem = table->tableHead; tableItem; tableItem = tableItem->next) if(tableItem->key == NULL) { /* This item has been deleted */ tableItem->key = cli_strdup(key); tableItem->value = value; return value; } table->flags &= ~TABLE_HAS_DELETED_ENTRIES; } table->tableLast = table->tableLast->next = (tableEntry *)cli_malloc(sizeof(tableEntry)); } if(table->tableLast == NULL) { cli_dbgmsg("tableInsert: Unable to allocate memory for table\n"); return -1; } table->tableLast->next = NULL; table->tableLast->key = cli_strdup(key); table->tableLast->value = value; return value; }
int hashtab_insert(struct hashtable *s,const unsigned char* key,const size_t len,const element_data data) { struct element* element; struct element* deleted_element = NULL; size_t tries = 1; size_t idx; if(!s) return CL_ENULLARG; do { PROFILE_CALC_HASH(s); idx = hash(key, len, s->capacity); element = &s->htable[idx]; do { if(!element->key) { unsigned char* thekey; /* element not found, place is empty, insert*/ if(deleted_element) { /* reuse deleted elements*/ element = deleted_element; PROFILE_DELETED_REUSE(s, tries); } else { PROFILE_INSERT(s, tries); } thekey = cli_malloc(len+1); if(!thekey) return CL_EMEM; strncpy((char*)thekey,(const char*)key,len+1); element->key = thekey; element->data = data; s->used++; if(s->used > s->maxfill) { cli_dbgmsg("hashtab.c:Growing hashtable %p, because it has exceeded maxfill, old size:%ld\n",(void*)s,s->capacity); hashtab_grow(s); } return 0; } else if(element->key == DELETED_KEY) { deleted_element = element; } else if(strncmp((const char*)key,(const char*)element->key,len)==0) { PROFILE_DATA_UPDATE(s, tries); element->data = data;/* key found, update */ return 0; } else { idx = (idx + tries++) % s->capacity; element = &s->htable[idx]; } } while (tries <= s->capacity); /* no free place found*/ PROFILE_HASH_EXHAUSTED(s); cli_dbgmsg("hashtab.c: Growing hashtable %p, because its full, old size:%ld.\n",(void*)s,s->capacity); } while( hashtab_grow(s) >= 0 ); cli_warnmsg("hashtab.c: Unable to grow hashtable\n"); return CL_EMEM; }
static int onas_ddd_watch_hierarchy(const char* pathname, size_t len, int fd, uint64_t mask, uint32_t type) { if (!pathname || fd <= 0 || !type) return CL_ENULLARG; if (type == (ONAS_IN | ONAS_FAN)) return CL_EARG; struct onas_hnode *hnode = NULL; struct onas_element *elem = NULL; int wd = 0; if(onas_ht_get(ddd_ht, pathname, len, &elem) != CL_SUCCESS) return CL_EARG; hnode = elem->data; if (type & ONAS_IN) { wd = inotify_add_watch(fd, pathname, (uint32_t) mask); if (wd < 0) return CL_EARG; if (wd >= wdlt_len) { onas_ddd_grow_wdlt(); } /* Link the hash node to the watch descriptor lookup table */ hnode->wd = wd; wdlt[wd] = hnode->pathname; hnode->watched |= ONAS_INWATCH; } else if (type & ONAS_FAN) { if(fanotify_mark(fd, FAN_MARK_ADD, mask, AT_FDCWD, hnode->pathname) < 0) return CL_EARG; hnode->watched |= ONAS_FANWATCH; } else { return CL_EARG; } struct onas_lnode *curr = hnode->childhead; while (curr->next != hnode->childtail) { curr = curr->next; size_t size = len + strlen(curr->dirname) + 2; char *child_path = (char *) cli_malloc(size); if (child_path == NULL) return CL_EMEM; if (hnode->pathname[len-1] == '/') snprintf(child_path, --size, "%s%s", hnode->pathname, curr->dirname); else snprintf(child_path, size, "%s/%s", hnode->pathname, curr->dirname); if(onas_ddd_watch_hierarchy(child_path, strlen(child_path), fd, mask, type)) { return CL_EARG; } free(child_path); } return CL_SUCCESS; }
int cli_jsonstrlen_nojson(const char* key, const char* s, int len) { char *sp = cli_malloc(len+1); strncpy(sp, s, len); sp[len] = '\0'; nojson_func("nojson: %s: %s\n", key, sp); free(sp); return CL_SUCCESS; }
void *__lzma_wrap_alloc(void *unused, size_t size) { if(!size || size > CLI_MAX_ALLOCATION) return NULL; unused = unused; if(!size || size > CLI_MAX_ALLOCATION) { cli_dbgmsg("lzma_wrap_alloc(): Attempt to allocate %lu bytes.\n", (unsigned long int) size); return NULL; } return cli_malloc(size); }
/* make a copy of the string between start -> end*/ static int string_assign_dup(struct string* dest,const char* start,const char* end) { char* ret = cli_malloc(end-start+1); if(!ret) return CL_EMEM; strncpy(ret,start,end-start); ret[end-start]='\0'; string_free(dest); string_init_c(dest, ret); return CL_SUCCESS; }
static char * get_unicode_name(const char *name, int size, int big_endian) { int i, increment; char *newname, *ret; if((name == NULL) || (*name == '\0') || (size <= 0)) return NULL; newname = (char *)cli_malloc(size * 7 + 1); if(newname == NULL) { cli_errmsg("get_unicode_name: Unable to allocate memory for newname\n"); return NULL; } if((!big_endian) && (size & 0x1)) { cli_dbgmsg("get_unicode_name: odd number of bytes %d\n", size); --size; } increment = (big_endian) ? 1 : 2; ret = newname; for(i = 0; i < size; i += increment) { if((!(name[i]&0x80)) && isprint(name[i])) { *ret++ = tolower(name[i]); } else { if((name[i] < 10) && (name[i] >= 0)) { *ret++ = '_'; *ret++ = (char)(name[i] + '0'); } else { uint16_t x; if ((i + 1) >= size) break; x = (uint16_t)((name[i] << 8) | name[i + 1]); *ret++ = '_'; *ret++ = (char)('a'+((x&0xF))); *ret++ = (char)('a'+((x>>4)&0xF)); *ret++ = (char)('a'+((x>>8)&0xF)); *ret++ = 'a'; *ret++ = 'a'; } *ret++ = '_'; } } *ret = '\0'; /* Saves a lot of memory */ ret = cli_realloc(newname, (ret - newname) + 1); return ret ? ret : newname; }
int cli_LzmaInit(CLI_LZMA **Lp, uint64_t size_override) { CLI_LZMA *L = *Lp; if(!L) { *Lp = L = cli_calloc(sizeof(*L), 1); if(!L) { return CL_EMEM; } } L->initted = 0; if(size_override) L->usize=size_override; if (!L->next_in || L->avail_in < LZMA_PROPERTIES_SIZE + 8) return LZMA_RESULT_OK; if (LzmaDecodeProperties(&L->state.Properties, L->next_in, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK) return LZMA_RESULT_DATA_ERROR; L->next_in += LZMA_PROPERTIES_SIZE; L->avail_in -= LZMA_PROPERTIES_SIZE; if (!L->usize) { L->usize=(uint64_t)cli_readint32(L->next_in) + ((uint64_t)cli_readint32(L->next_in+4)<<32); L->next_in += 8; L->avail_in -= 8; } if (!(L->state.Probs = (CProb *)cli_malloc(LzmaGetNumProbs(&L->state.Properties) * sizeof(CProb)))) return LZMA_RESULT_DATA_ERROR; if (!(L->state.Dictionary = (unsigned char *)cli_malloc(L->state.Properties.DictionarySize))) { free(L->state.Probs); return LZMA_RESULT_DATA_ERROR; } L->initted = 1; LzmaDecoderInit(&L->state); return LZMA_RESULT_OK; }
/* assigns to @dest the string made from concatenating @prefix with the string between @begin and @end */ static int string_assign_concatenated(struct string* dest, const char* prefix, const char* begin, const char* end) { const size_t prefix_len = strlen(prefix); char* ret = cli_malloc(prefix_len + end - begin + 1); if(!ret) return CL_EMEM; strncpy(ret, prefix, prefix_len); strncpy(ret+prefix_len, begin, end-begin); ret[prefix_len+end-begin]='\0'; string_free(dest); string_init_c(dest, ret); return CL_SUCCESS; }
static int onas_ddd_unwatch_hierarchy(const char* pathname, size_t len, int fd, uint32_t type) { if (!pathname || fd <= 0 || !type) return CL_ENULLARG; if (type == (ONAS_IN | ONAS_FAN)) return CL_EARG; struct onas_hnode *hnode = NULL; struct onas_element *elem = NULL; int wd = 0; if(onas_ht_get(ddd_ht, pathname, len, &elem)) return CL_EARG; hnode = elem->data; if (type & ONAS_IN) { wd = hnode->wd; if(!inotify_rm_watch(fd, wd)) return CL_EARG; /* Unlink the hash node from the watch descriptor lookup table */ hnode->wd = 0; wdlt[wd] = NULL; hnode->watched = ONAS_STOPWATCH; } else if (type & ONAS_FAN) { if(fanotify_mark(fd, FAN_MARK_REMOVE, 0, AT_FDCWD, hnode->pathname) < 0) return CL_EARG; hnode->watched = ONAS_STOPWATCH; } else { return CL_EARG; } struct onas_lnode *curr = hnode->childhead; while (curr->next != hnode->childtail) { curr = curr->next; size_t size = len + strlen(curr->dirname) + 2; char *child_path = (char *) cli_malloc(size); if (child_path == NULL) return CL_EMEM; if (hnode->pathname[len-1] == '/') snprintf(child_path, --size, "%s%s", hnode->pathname, curr->dirname); else snprintf(child_path, size, "%s/%s", hnode->pathname, curr->dirname); onas_ddd_unwatch_hierarchy(child_path, strlen(child_path), fd, type); free(child_path); } return CL_SUCCESS; }
/* make a copy of the string between start -> end*/ static int string_assign_dup(struct string* dest,const char* start,const char* end) { char* ret = cli_malloc(end-start+1); if(!ret) { cli_errmsg("Phishcheck: Unable to allocate memory for string_assign_dup\n"); return CL_EMEM; } strncpy(ret,start,end-start); ret[end-start]='\0'; string_free(dest); string_init_c(dest, ret); return CL_SUCCESS; }
/* make a copy of the string between start -> end*/ static int string_assign_dup(struct string* dest,const char* start,const char* end) { char* ret = cli_malloc(end-start+1); if(!ret) return CL_EMEM; strncpy(ret,start,end-start); ret[end-start]='\0'; string_free(dest); dest->data=ret; dest->refcount=1; dest->ref=NULL; return CL_SUCCESS; }
static char* str_compose(const char* a,const char* b,const char* c) { const size_t a_len = strlen(a); const size_t b_len = strlen(b); const size_t c_len = strlen(c); const size_t r_len = a_len+b_len+c_len+1; char* concated = cli_malloc(r_len); if(!concated) return NULL; strncpy(concated,a,a_len); strncpy(concated+a_len,b,b_len); strncpy(concated+a_len+b_len,c,c_len); concated[r_len-1]='\0'; return concated; }
int cli_jsonstrlen_nojson(const char* key, const char* s, int len) { char *sp = cli_malloc(len+1); if (NULL == sp) { cli_errmsg("json: no memory for json strlen object.\n"); return CL_EMEM; } strncpy(sp, s, len); sp[len] = '\0'; nojson_func("nojson: %s: %s\n", key, sp); free(sp); return CL_SUCCESS; }
/* assigns to @dest the string made from concatenating @prefix with the string between @begin and @end */ static int string_assign_concatenated(struct string* dest, const char* prefix, const char* begin, const char* end) { const size_t prefix_len = strlen(prefix); char* ret = cli_malloc(prefix_len + end - begin + 1); if(!ret) { cli_errmsg("Phishcheck: Unable to allocate memory for string_assign_concatonated\n"); return CL_EMEM; } strncpy(ret, prefix, prefix_len); strncpy(ret+prefix_len, begin, end-begin); ret[prefix_len+end-begin]='\0'; string_free(dest); string_init_c(dest, ret); return CL_SUCCESS; }
struct uniq *uniq_init(uint32_t count) { struct uniq *U; if(!count) return NULL; U = cli_calloc(1, sizeof(*U)); if(!U) return NULL; U->md5s = cli_malloc(count * sizeof(*U->md5s)); if(!U->md5s) { uniq_free(U); return NULL; } return U; }
line_t * lineCreate(const char *data) { const size_t size = strlen(data); line_t *ret = (line_t *)cli_malloc(size + 2); if(ret == NULL) return (line_t *)NULL; ret[0] = (char)1; /*strcpy(&ret[1], data);*/ memcpy(&ret[1], data, size); ret[size + 1] = '\0'; return ret; }
int prtn_intxn_list_check(prtn_intxn_list_t* list, unsigned *pitxn, off_t start, size_t size) { prtn_intxn_node_t *new_node, *check_node; int ret = CL_CLEAN; *pitxn = list->Size; check_node = list->Head; while (check_node != NULL) { (*pitxn)--; if (start > check_node->Start) { if (check_node->Start+check_node->Size > start) { ret = CL_VIRUS; break; } } else if (start < check_node->Start) { if (start+size > check_node->Start) { ret = CL_VIRUS; break; } } else { ret = CL_VIRUS; break; } check_node = check_node->Next; } /* allocate new node for partition bounds */ new_node = (prtn_intxn_node_t *) cli_malloc(sizeof(prtn_intxn_node_t)); if (!new_node) { cli_dbgmsg("PRTN_INTXN: could not allocate new node for checklist!\n"); prtn_intxn_list_free(list); return CL_EMEM; } new_node->Start = start; new_node->Size = size; new_node->Next = list->Head; list->Head = new_node; (list->Size)++; return ret; }
void diff_files(int fd, int ref_fd) { char *ref; ssize_t nread; off_t siz = lseek(ref_fd, 0, SEEK_END); fail_unless_fmt(siz != -1, "lseek failed"); ref = cli_malloc(siz); fail_unless_fmt(!!ref, "unable to malloc buffer: %d", siz); fail_unless_fmt(lseek(ref_fd, 0, SEEK_SET) == 0,"lseek failed"); nread = read(ref_fd, ref, siz); fail_unless_fmt(nread == siz, "short read, expected: %ld, was: %ld", siz, nread); close(ref_fd); diff_file_mem(fd, ref, siz); free(ref); }
static int isTLD(const struct phishcheck* pchk,const char* str,int len) { if (!str) return 0; else { char* s = cli_malloc(len+1); int rc; if(!s) return CL_EMEM; strncpy(s,str,len); s[len]='\0'; rc = !cli_regexec(&pchk->preg_tld,s,0,NULL,0); free(s); return rc ? 1 : 0; } }
line_t * lineCreate(const char *data) { line_t *ret = (line_t *)cli_malloc(sizeof(struct line)); if(ret == NULL) return NULL; ret->l_str = strdup(data); if(ret->l_str == NULL) { free(ret); return NULL; } ret->l_refs = 1; return ret; }
/* Add a copy of a text to the end of the current object */ static text * textAdd(text *t_head, const text *t) { text *ret; int count; if(t_head == NULL) { if(t == NULL) { cli_errmsg("textAdd fails sanity check\n"); return NULL; } return textCopy(t); } if(t == NULL) return t_head; ret = t_head; count = 0; while(t_head->t_next) { count++; t_head = t_head->t_next; } cli_dbgmsg("textAdd: count = %d\n", count); while(t) { t_head->t_next = (text *)cli_malloc(sizeof(text)); t_head = t_head->t_next; assert(t_head != NULL); if(t->t_line) t_head->t_line = lineLink(t->t_line); else t_head->t_line = NULL; t = t->t_next; } t_head->t_next = NULL; return ret; }