piskvorky / bounter

Efficient Counter that uses a limited (bounded) amount of memory regardless of data size.
MIT License
936 stars 47 forks source link

Potential Null pointer access in CMS_Conservative_increment_obj #47

Open awen-li opened 3 years ago

awen-li commented 3 years ago

Description

In CMS_Conservative_init, w is received from Python code. Its size is not validated hence "self->table[i] = (CMS_CELL_TYPE *) calloc(self->width, sizeof(CMS_CELL_TYPE));" may fail , which cause the Null pointer. self->table[i] would be accessed in CMS_Conservative_increment_obj, which make the Python crash down.

Steps/Code/Corpus to Reproduce

static int
CMS_VARIANT(_init)(CMS_TYPE *self, PyObject *args, PyObject *kwds)
{
    .........................
    for (i = 0; i < self->depth; i++)
    {
        self->table[i] = (CMS_CELL_TYPE *) calloc(self->width, sizeof(CMS_CELL_TYPE));
        printf ("[%d]self->table[%d] = %p \r\n", i, i, self->table[i]);
    }
    ...........................

Optional call-path: increment -> CMS_Log1024_increment -> CMS_Conservative_increment_obj

Expected Results

when w is set as an arbitrary number, Python can not crash down.

Actual Results

crash

Versions

the main branch

awen-li commented 3 years ago

PoC:

from bounter import CountMinSketch

Cms = None LogCounting = None

def setUp(LogCounting = None): return CountMinSketch(1, width=2**31, depth=32, log_counting=LogCounting)

Cms = setUp () for i in range (0, 100): Cms.increment('foo') Cms.increment('bar')

print (Cms['foo']) print (Cms['bar'])

Crash: Segmentation fault (core dumped)

piskvorky commented 3 years ago

@Daybreak2019 can you open a PR with a fix? Thanks!

eric-wieser commented 2 years ago

FWIW, this seems to have had a CVE opened against it: https://nvd.nist.gov/vuln/detail/CVE-2021-41497