Vulnerabilities in languages (mostly C/C++)

Not memory safe: programmers can read/write memory freely and are not constrained by the address or size of the variables.

  • Great flexibility, but huge risk as mistakes lead to accessing memory that otherwise should not be accessed.

  • C/C++ compilers have freedom to optimize code and even sometimes undefined behavior.

Memory safe languages intercept such errors, raising errors.

  • Program will crash (DoS), but impact is limited.

// Correct usage
printf("%d\n", *value);

// Reading memory after the variable
printf("%d\n", *(value + 4));

// Reading memory before the variable
printf("%d\n", *(value - 4));

Not type safe: memory content can be reinterpreted as required by the programmer.

  • Casts may be arbitrarily allowed and not checked.

Type safe languages do not allow reinterpretation, or only safe reintrepertation.

  • Cast a byte to int is safe, a buffer to int is not.

int value = 42;

// Correct usage
printf("%d\n", value);

// Cast to variable with different storage
printf("%f\n", *((double*) &value));

// Cast to variable with different size
printf("%llu\n", *((unsigned long long*) &value));

Dynamically allocated memory has no implicit management mechanism.

  • Programmer must allocate and deallocate all memory.

  • Programmer must know how memory was allocated.

  • Programmer must free memory only after there is no other reference.

char* buffer = (char*) malloc(10);
char* str = buffer;

free(buffer);

// Write after free (and write beyond buffer)
memcpy(str, "Hello World!!!!", 15);
// Read after free (and read beyond buffer)
printf("%s\n", str);

Last updated