Skip to content

Problems with multiple allocation sites #215

Open
@peckto

Description

@peckto

The following c code has two allocation sites for the memory referenced by pointer data, with different size values:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

void foo()
{
    char * data;
    if ((rand() % 2) == 0)
    {
        data = malloc(11);
//        if (data == NULL) {exit(-1);}
    }
    else
    {
        data = malloc(10);
//        if (data == NULL) {exit(-1);}
    }
    char source[11];
    memcpy(data, source, sizeof(source));
    free(data);
}

int main() {
    foo();
    return 0;
}

When analyzing this code with IKOS, the buffer overflow bug in case of the else branch (malloc(10)) is not detected.
Instead, IKOS reports a possible use after free and a possible double free bug:

# Results
main2.c: In function 'foo':
main2.c:19:9: warning: possible use after free, pointer 'data' points to:
                       	* dynamic memory allocated at 'foo:10:16', which might be released
                       	* dynamic memory allocated at 'foo:15:16', which might be released
        memcpy(data, source, sizeof(source));
        ^
main2.c: In function 'foo':
main2.c:20:9: warning: possible double free, pointer 'data' points to:
                       	* dynamic memory allocated at 'foo:10:16', which might be already released
                       	* dynamic memory allocated at 'foo:15:16', which might be already released
        free(data);
        ^

The listed allocations sites are correct, but the memory is not freed.
(Is there any way, that IKOS reports where it thinks the free happens?)

I tried all available abstract domains (including APRON), with the same results, except congruence domain.
With the congruence domain, additionally the following error is reported:

main2.c: In function 'foo':
main2.c:19:9: warning: possible buffer overflow, pointer '&source[0]' accesses 11 bytes at offset 0 bytes of local variable 'source' of size 11 bytes
        memcpy(data, source, sizeof(source));
        ^

Either the finding is indeed related to data instead of source and the message is wrong, or the finding is false positive.

A similar issue is #52, but in my case no pointer to int conversion happens.

When I modify the example to have only one allocation site, with two possible size values, IKOS successfully detects the bug:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>


void foo()
{
    char *data;
    int len;
    if ((rand() % 2) == 0)
    {
        len = 11;
    }
    else
    {
        len = 10;
    }
    data = malloc(len);
    char source[11];
    memcpy(data, source, sizeof(source));
    free(data);
}

int main() {
    foo();
    return 0;
}
# Results
main4.c: In function 'foo':
main4.c:20:5: warning: pointer 'data' might be null
    memcpy(data, source, len);
    ^
main4.c: In function 'foo':
main4.c:20:5: warning: possible buffer overflow, pointer 'data' accesses 11 bytes at offset 0 bytes of dynamic memory allocated at 'foo:18:12' of size at most 11 bytes
    memcpy(data, source, len);
    ^

I know, dynamically allocated memory is not the main priority of IKOS,
still I'm confused why it works in the one case and not in the other.
Can you describe, why this is the case?
Is this a known limitation, or a bug?
Do I need some additional analyzer options?
Or have I missed something else?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions