Will any programs detect buffer overflows in a C / C ++ structure?

Consider the following program:

struct abc { int x[5]; int y[5]; }; int main() { struct abc test; test.y[0] = 10; printf("%d", test.x[5]); } 

(borrowed from Is it legal to intercept one element of a structure to view another? )

BoundsChecker does not detect this as an overflow. Are there any programs that will detect this type of programming error?

+4
source share
2 answers

clang does even without special flags:

 $ clang example.c -o example example.c:13:18: warning: array index of '5' indexes past the end of an array (that contains 5 elements) [-Warray-bounds] printf("%d", test.x[5]); ^ ~ example.c:5:5: note: array 'x' declared here int x[5]; ^ 1 warning generated. 

The same warning is printed when compiling as C ++.

+6
source

What we see here is an unpleasant, little-known secret about BoundsChecker: it does not give structure members visibility at all. If you declare an array as part of a structure, whether that structure is distributed automatically or dynamically, BoundsChecker sees the structure as a blob. If you exceed the boundaries of this structure, it will report a problem. Otherwise, no.

However, a few years ago we wrote code that comes with the product at the moment and which can be invoked with a hidden configuration. If you manually entered the line EnableStructureMemberEnumeration=1 in the [BC MemoryTracker] section of the project configuration file ( .dpbcd ), you will find that the product can see structure elements (structures and arrays, mainly) for how long since this structure is allocated automatically (on the stack )

This option is not yet ready for prime time. This has problems with very complex classes and structures that are in the STL. In addition, in the specific test case above, another problem arises. It generally cannot distinguish between an array that runs the structure / class and the class object itself. Both have the same address in memory. But consider this code:

 struct _Type { int Array[5]; } Objects[10]; struct _Type *pObject = &Objects[5]; int *pInt = &Objects[0].Array[5]; 

In both cases, we see the same address, the first time with an offset of 100, the second time with an offset of 20. The first, if evaluated with respect to Array , is invalid, but if it is evaluated with reference to Objects . What is a bad program?

Oh, and one more thing: BoundsChecker usually ignores access to the first element beyond the end of the array. This is because there is so much code where the iterator will only go through one element at the end. It was a huge source of false errors, so someone changed it to complain only if the overspending moved to the next place (and beyond). The problem here is that you increased the iterator, but are you going to use it?

So, at the moment, the answer to the question is that BoundsChecker really supports this type of validation, but not without the use of an undocumented β€œfunction” and not without problems.

+2
source

Source: https://habr.com/ru/post/1386135/


All Articles