Buffer overflow not detected in C code

The C code snippet is exhibiting a buffer overflow vulnerability when the initial element in the array exceeds 9, which is currently not being flagged by the sonar scanner. It is advisable to implement a sonar rule addressing this issue, emphasizing the importance of not accessing memory locations outside of your allocated space.

Could you please Sonar team take a look at it?

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

unsigned char first_value = 0;

void fill_array(unsigned char arr[]) {
    for (int i = 0; i < 10; i++) {
        arr[i] = (unsigned char)rand() % 256; // Generate random values between 0 and 255
    }
}

void print_array(unsigned char arr[]) {
    for (int i = 0; i < 10; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    unsigned char arr[10];
    srand(time(NULL)); // Seed the random number generator

    fill_array(arr);
    print_array(arr);

    first_value = arr[0];
    printf("First value: %d\n", first_value);

    unsigned char * buffer = &arr[0];
    buffer = buffer+1;  //do not modify first element. that's why we skip it
    
    for (int i = 1; i < first_value+1; i++) {
        buffer[0] = 0; // Fill the following elements with 0; possible **BUFFER OVERFLOW!!**
        buffer = buffer + 1;
    }

    printf("\n");
    print_array(arr);

    return 0;
}

I am using SonarQube EE 9.9

Hi @Dominik,

Thanks for coming back and leaving this feedback.

I’ve got some bad news for you, unfortunately. It’s a long-standing problem, and we don’t really have a solution to this. I recorded this issue in CPP-5368.

If you are interested in what makes this challenging, continue reading.


Basically, one could transform your example into this one:

void top(int rng) {
    char arr[10];
    int mod256 = rng % 256;

    // The bound is known to be at most 255.
    for (int i = 0; i < mod256; ++i) {
        arr[i] = 0; // Fill the following elements with 0; possible **BUFFER OVERFLOW!!**
    }
}

We don’t know the exact value for rng here, so it can be anything from INT_MIN to INT_MAX.
We are actually smart about the value of mod256, and we can prove that it must be in the range [-255,255] due to the modulo operation.
The real problem is that we only simulate up to 4 iterations for loops. Since we don’t hit the bug within the first 4 iterations, we don’t find it.
If we changed the engine to do more iterations—let’s say we allow 12 iterations—then we would diagnose the out-of-bounds access, as you expect.
However, increasing loop iterations could possibly make our performance much worse for deeply nested loops, dragging the already long-running analysis time.

One could have some other mechanism for detecting out-of-bounds accesses within loops in particular, but we don’t have anything of that sort on the table at the moment.

1 Like