Currently, LLVM's ability to detect buffer overflows is based on two things:
Compile time warning -Wfortify-source
Run time error with _FORTIFY_SOURCE
There are a lot of cases which are not covered by the -Wfortify-source warning and the run time error only happens when FORTIFY_SOURCE concept is enabled with the -D_FORTIFY_SOURCE={1, 2, 3} flag (even then not all cases are caught). Therefore, there is room for improvement regarding the detection of buffer overflows.
This issue proposes the addition of a new LLVM CodeGen pass which would attempt to detect buffer overflows in calls to memcpy/memmove/memset/strncpy/bcopy/bzero functions at compile time and issue appropriate warnings/errors if successfull. This should be an improvement on both of the already existing ways to detect buffer overflows as it does the warning/error generation in compile time (better than at run time) and it covers some cases which -Wfortify-source does not. One of those cases is given in the example below which contains a buffer overflow (memcpy.c).
#include <string.h>
#define STATIC_BUF_SIZE 10
char th_dst[STATIC_BUF_SIZE]; /* Destination buffer */
char th_src[STATIC_BUF_SIZE]; /* Source buffer */
int main() {
int size = STATIC_BUF_SIZE + 1;
bzero(th_dst, STATIC_BUF_SIZE);
for (int i = 0; i < STATIC_BUF_SIZE; i++)
th_src[i] = (unsigned char)(i + 1);
memcpy(th_dst, th_src, size);
return 0;
}
Compiling this test case into executable and its execution looks like this:
Note that the overflow is either not caught (without FORTIFY_SOURCE) or caught at run time only (with FORTIFY_SOURCE). However, in this case, we should be able to detect it at compile time as both the length and size of the destination pointer is known at compile time, when compiled with optimizations.
I implemented a pass as discussed above and can now report a compile time warning for mentioned test case:
bash-4.4$ clang -O2 memcpy.c -o a.out
warning: 'llvm.memcpy.p0i8.p0i8.i64' writing 11 bytes into a region of size 10 bytes (80 bits) overflows the destination
Note that the warning message is not the same as the warnings issued by Clang, for example, as the optimizer lacks the proper infrastructure to generate warnings (at least to my knowledge). This can definitely be further improved.
Detecting such issues at compile time (even if not enabled by default) would be greatly desirable rather than at run time. If this is agreeable, I would be interested in working more on a patch which improves buffer overflow detection at compile time.
Currently, LLVM's ability to detect buffer overflows is based on two things:
There are a lot of cases which are not covered by the -Wfortify-source warning and the run time error only happens when FORTIFY_SOURCE concept is enabled with the -D_FORTIFY_SOURCE={1, 2, 3} flag (even then not all cases are caught). Therefore, there is room for improvement regarding the detection of buffer overflows.
This issue proposes the addition of a new LLVM CodeGen pass which would attempt to detect buffer overflows in calls to memcpy/memmove/memset/strncpy/bcopy/bzero functions at compile time and issue appropriate warnings/errors if successfull. This should be an improvement on both of the already existing ways to detect buffer overflows as it does the warning/error generation in compile time (better than at run time) and it covers some cases which -Wfortify-source does not. One of those cases is given in the example below which contains a buffer overflow (memcpy.c).
Compiling this test case into executable and its execution looks like this:
bash-4.4$ clang -O2 memcpy.c -o a.out // no compile-time warning bash-4.4$ ./a.out bash-4.4$
If -D_FORTIFY_SOURCE=2 option is also specified, there will be a run time error which is:
buffer overflow detected : terminated Aborted (core dumped)
Note that the overflow is either not caught (without FORTIFY_SOURCE) or caught at run time only (with FORTIFY_SOURCE). However, in this case, we should be able to detect it at compile time as both the length and size of the destination pointer is known at compile time, when compiled with optimizations.
I implemented a pass as discussed above and can now report a compile time warning for mentioned test case:
bash-4.4$ clang -O2 memcpy.c -o a.out warning: 'llvm.memcpy.p0i8.p0i8.i64' writing 11 bytes into a region of size 10 bytes (80 bits) overflows the destination
Note that the warning message is not the same as the warnings issued by Clang, for example, as the optimizer lacks the proper infrastructure to generate warnings (at least to my knowledge). This can definitely be further improved.
Detecting such issues at compile time (even if not enabled by default) would be greatly desirable rather than at run time. If this is agreeable, I would be interested in working more on a patch which improves buffer overflow detection at compile time.