예제 #1
0
fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty) { /* WIN32 */
    unsigned int pages, mapsz, hdrsz;
    int pgsz = cli_getpagesize();
    STATBUF st;
    fmap_t *m;
    const void *data;
    HANDLE fh;
    HANDLE mh;

    *empty = 0;
    if(FSTAT(fd, &st)) {
	cli_warnmsg("fmap: fstat failed\n");
	return NULL;
    }
    if(offset < 0 || offset != fmap_align_to(offset, pgsz)) {
	cli_warnmsg("fmap: attempted mapping with unaligned offset\n");
	return NULL;
    }
    if(!len) len = st.st_size - offset; /* bound checked later */
    if(!len) {
	cli_dbgmsg("fmap: attempted void mapping\n");
	*empty = 1;
	return NULL;
    }
    if(!CLI_ISCONTAINED(0, st.st_size, offset, len)) {
	cli_warnmsg("fmap: attempted oof mapping\n");
	return NULL;
    }

    pages = fmap_align_items(len, pgsz);
    hdrsz = fmap_align_to(sizeof(fmap_t), pgsz);

    if((fh = (HANDLE)_get_osfhandle(fd)) == INVALID_HANDLE_VALUE) {
	cli_errmsg("fmap: cannot get a valid handle for descriptor %d\n", fd);
	return NULL;
    }
    if(!(mh = CreateFileMapping(fh, NULL, PAGE_READONLY, (DWORD)((len>>31)>>1), (DWORD)len, NULL))) {
	cli_errmsg("fmap: cannot create a map of descriptor %d\n", fd);
	CloseHandle(fh);
	return NULL;
    }
    if(!(data = MapViewOfFile(mh, FILE_MAP_READ, (DWORD)((offset>>31)>>1), (DWORD)(offset), len))) {
	cli_errmsg("fmap: cannot map file descriptor %d\n", fd);
	CloseHandle(mh);
	CloseHandle(fh);
	return NULL;
    }
    if(!(m = cl_fmap_open_memory(data, len))) {
	cli_errmsg("fmap: canot allocate fmap_t\n", fd);
	CloseHandle(mh);
	CloseHandle(fh);
	return NULL;
    }
    m->handle = (void*)(ssize_t)fd;
    m->handle_is_fd = 1;
    m->fh = fh;
    m->mh = mh;
    m->unmap = unmap_win32;
    return m;
}
예제 #2
0
extern cl_fmap_t *cl_fmap_open_memory(const void *start, size_t len)
{
    int pgsz = cli_getpagesize();
    cl_fmap_t *m = cli_calloc(1, sizeof(*m));
    if (!m) {
	cli_warnmsg("fmap: map allocation failed\n");
	return NULL;
    }
    m->data = start;
    m->len = len;
    m->real_len = len;
    m->pgsz = pgsz;
    m->pages = fmap_align_items(len, pgsz);
    m->unmap = unmap_malloc;
    m->need = mem_need;
    m->need_offstr = mem_need_offstr;
    m->gets = mem_gets;
    m->unneed_off = mem_unneed_off;
    return m;
}
예제 #3
0
파일: blob.c 프로젝트: nsxz/clamav-devel
/*
 * Returns <0 for failure
 */
int
blobAddData(blob *b, const unsigned char *data, size_t len)
{
#if	HAVE_CLI_GETPAGESIZE
    static int pagesize;
    int growth;
#endif

    assert(b != NULL);
    assert(b->magic == BLOBCLASS);
    assert(data != NULL);

    if(len == 0)
        return 0;

    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("Reopening closed blob\n");
        b->isClosed = 0;
    }
    /*
     * The payoff here is between reducing the number of calls to
     * malloc/realloc and not overallocating memory. A lot of machines
     * are more tight with memory than one may imagine which is why
     * we don't just allocate a *huge* amount and be done with it. Closing
     * the blob helps because that reclaims memory. If you know the maximum
     * size of a blob before you start adding data, use blobGrow() that's
     * the most optimum
     */
#if	HAVE_CLI_GETPAGESIZE
    if(pagesize == 0) {
        pagesize = cli_getpagesize();
        if(pagesize == 0)
            pagesize = 4096;
    }
    growth = pagesize;
    if(len >= (size_t)pagesize)
        growth = ((len / pagesize) + 1) * pagesize;

    /*cli_dbgmsg("blobGrow: b->size %lu, b->len %lu, len %lu, growth = %u\n",
    	b->size, b->len, len, growth);*/

    if(b->data == NULL) {
        assert(b->len == 0);
        assert(b->size == 0);

        b->size = growth;
        b->data = cli_malloc(growth);
    } else if(b->size < b->len + (off_t)len) {
        unsigned char *p = cli_realloc(b->data, b->size + growth);

        if(p == NULL)
            return -1;

        b->size += growth;
        b->data = p;
    }
#else
    if(b->data == NULL) {
        assert(b->len == 0);
        assert(b->size == 0);

        b->size = (off_t)len * 4;
        b->data = cli_malloc(b->size);
    } else if(b->size < b->len + (off_t)len) {
        unsigned char *p = cli_realloc(b->data, b->size + (len * 4));

        if(p == NULL)
            return -1;

        b->size += (off_t)len * 4;
        b->data = p;
    }
#endif

    if(b->data) {
        memcpy(&b->data[b->len], data, len);
        b->len += (off_t)len;
    }
    return 0;
}
예제 #4
0
extern cl_fmap_t *cl_fmap_open_handle(void *handle, size_t offset, size_t len,
				      clcb_pread pread_cb, int use_aging)
{
    unsigned int pages, mapsz, hdrsz;
    cl_fmap_t *m;
    int pgsz = cli_getpagesize();

    if((off_t)offset < 0 || offset != fmap_align_to(offset, pgsz)) {
	cli_warnmsg("fmap: attempted mapping with unaligned offset\n");
	return NULL;
    }
    if(!len) {
	cli_dbgmsg("fmap: attempted void mapping\n");
	return NULL;
    }
    if (offset >= len) {
	cli_warnmsg("fmap: attempted oof mapping\n");
	return NULL;
    }

    pages = fmap_align_items(len, pgsz);
    hdrsz = fmap_align_to(sizeof(fmap_t) + (pages-1) * sizeof(uint32_t), pgsz); /* fmap_t includes 1 bitmap slot, hence (pages-1) */
    mapsz = pages * pgsz + hdrsz;

#ifndef ANONYMOUS_MAP
    use_aging = 0;
#endif
#ifdef ANONYMOUS_MAP
    if (use_aging) {
	fmap_lock;
	if ((m = (fmap_t *)mmap(NULL, mapsz, PROT_READ | PROT_WRITE, MAP_PRIVATE|/*FIXME: MAP_POPULATE is ~8% faster but more memory intensive */ANONYMOUS_MAP, -1, 0)) == MAP_FAILED) {
	    m = NULL;
	} else {
#if HAVE_MADVISE
	    madvise((void *)m, mapsz, MADV_RANDOM|MADV_DONTFORK);
#endif /* madvise */
	    /* fault the header while we still have the lock - we DO context switch here a lot here :@ */
	    memset(fmap_bitmap, 0, sizeof(uint32_t) * pages);
	}
	fmap_unlock;
    }
#endif /* ANONYMOUS_MAP */
    if (!use_aging) {
	m = (fmap_t *)cli_malloc(mapsz);
    if (!(m)) {
        cli_warnmsg("fmap: map allocation failed\n");
        return NULL;
    }
	memset(m, 0, hdrsz);
    }
    if(!m) {
	cli_warnmsg("fmap: map allocation failed\n");
	return NULL;
    }
    m->handle = handle;
    m->pread_cb = pread_cb;
    m->aging = use_aging;
    m->offset = offset;
    m->nested_offset = 0;
    m->len = len;/* m->nested_offset + m->len = m->real_len */
    m->real_len = len;
    m->pages = pages;
    m->hdrsz = hdrsz;
    m->pgsz = pgsz;
    m->paged = 0;
    m->dont_cache_flag = 0;
    m->unmap = use_aging ? unmap_mmap : unmap_malloc;
    m->need = handle_need;
    m->need_offstr = handle_need_offstr;
    m->gets = handle_gets;
    m->unneed_off = handle_unneed_off;
    return m;
}
예제 #5
0
fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty) {
    unsigned int pages, mapsz, hdrsz;
    unsigned short dumb = 1;
    int pgsz = cli_getpagesize();
    struct stat st;
    fmap_t *m;

    *empty = 0;
    if(fstat(fd, &st)) {
	cli_warnmsg("fmap: fstat failed\n");
	return NULL;
    }
    if(offset < 0 || offset != fmap_align_to(offset, pgsz)) {
	cli_warnmsg("fmap: attempted mapping with unaligned offset\n");
	return NULL;
    }
    if(!len) len = st.st_size - offset; /* bound checked later */
    if(!len) {
	cli_dbgmsg("fmap: attempted void mapping\n");
	*empty = 1;
	return NULL;
    }
    if(!CLI_ISCONTAINED(0, st.st_size, offset, len)) {
	cli_warnmsg("fmap: attempted oof mapping\n");
	return NULL;
    }

    pages = fmap_align_items(len, pgsz);
    hdrsz = fmap_align_to(sizeof(fmap_t) + (pages-1) * sizeof(uint32_t), pgsz); /* fmap_t includes 1 bitmap slot, hence (pages-1) */
    mapsz = pages * pgsz + hdrsz;
    fmap_lock;
#ifdef ANONYMOUS_MAP
    if ((m = (fmap_t *)mmap(NULL, mapsz, PROT_READ | PROT_WRITE, MAP_PRIVATE|/*FIXME: MAP_POPULATE is ~8% faster but more memory intensive */ANONYMOUS_MAP, -1, 0)) == MAP_FAILED) {
	m = NULL;
    } else {
	dumb = 0;
#if HAVE_MADVISE
	madvise((void *)m, mapsz, MADV_RANDOM|MADV_DONTFORK);
#endif /* madvise */
    }
#else /* ! ANONYMOUS_MAP */
    m = (fmap_t *)cli_malloc(mapsz);
#endif /* ANONYMOUS_MAP */
    if(!m) {
	cli_warnmsg("fmap: map allocation failed\n");
	fmap_unlock;
	return NULL;
    }
    /* fault the header while we still have the lock - we DO context switch here a lot here :@ */
    memset(fmap_bitmap, 0, sizeof(uint32_t) * pages);
    fmap_unlock;
    m->fd = fd;
    m->dumb = dumb;
    m->mtime = st.st_mtime;
    m->offset = offset;
    m->len = len;
    m->pages = pages;
    m->hdrsz = hdrsz;
    m->pgsz = pgsz;
    m->paged = 0;
    m->dont_cache_flag = 0;
    return m;
}
예제 #6
0
fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty) { /* WIN32 */
    unsigned int pages, mapsz, hdrsz;
    unsigned short dumb = 1;
    int pgsz = cli_getpagesize();
    struct stat st;
    fmap_t *m;

    *empty = 0;
    if(fstat(fd, &st)) {
	cli_warnmsg("fmap: fstat failed\n");
	return NULL;
    }
    if(offset < 0 || offset != fmap_align_to(offset, pgsz)) {
	cli_warnmsg("fmap: attempted mapping with unaligned offset\n");
	return NULL;
    }
    if(!len) len = st.st_size - offset; /* bound checked later */
    if(!len) {
	cli_dbgmsg("fmap: attempted void mapping\n");
	*empty = 1;
	return NULL;
    }
    if(!CLI_ISCONTAINED(0, st.st_size, offset, len)) {
	cli_warnmsg("fmap: attempted oof mapping\n");
	return NULL;
    }

    pages = fmap_align_items(len, pgsz);
    hdrsz = fmap_align_to(sizeof(fmap_t), pgsz);

    if(!(m = (fmap_t *)cli_malloc(sizeof(fmap_t)))) {
	cli_errmsg("fmap: canot allocate fmap_t\n", fd);
	return NULL;
    }
    if((m->fh = (HANDLE)_get_osfhandle(fd)) == INVALID_HANDLE_VALUE) {
	cli_errmsg("fmap: cannot get a valid handle for descriptor %d\n", fd);
	free(m);
	return NULL;
    }
    if(!(m->mh = CreateFileMapping(m->fh, NULL, PAGE_READONLY, (DWORD)((len>>31)>>1), (DWORD)len, NULL))) {
	cli_errmsg("fmap: cannot create a map of descriptor %d\n", fd);
	free(m);
	return NULL;
    }
    if(!(m->data = MapViewOfFile(m->mh, FILE_MAP_READ, (DWORD)((offset>>31)>>1), (DWORD)(offset), len))) {
	cli_errmsg("fmap: cannot map file descriptor %d\n", fd);
	CloseHandle(m->mh);
	free(m);
	return NULL;
    }
    m->fd = fd;
    m->dumb = dumb;
    m->mtime = st.st_mtime;
    m->offset = offset;
    m->len = len;
    m->pages = pages;
    m->hdrsz = hdrsz;
    m->pgsz = pgsz;
    m->paged = 0;
    m->dont_cache_flag = 0;
    return m;
}