GCC optimisation removes security checks
The developers of the open source GCC compiler collection have changed several basic assumptions in the way the software works. As a result, optimisation routines may remove some length checks at compile time. This can make programs generated with these compilers vulnerable to buffer overflows. Although the problem apparently became known two years ago, US-CERT has only just issued a warning about the change.
In operations which include the
char *buf;
int len;
data types, gcc compilers from version 4.1 assume that the sum of buf
and len
is always greater than the value of buf
. If the program code contains checks based on pointer arithmetic, such as
if(buf+len < buf) { … }
the compiler removes the check and the function block. An integer overflow may cause this assumption to be incorrect and make the generated binary code vulnerable to a buffer overflow.
As early as April 2006, CCC member Felix von Leitner notified gcc's developers of this issue. According to an entry in the Bugtracker system, the developers did subsequently integrate a patch into the sources, but this patch doesn't seem to resolve the problem.
US-CERT explains in a vulnerability note how programmers can avoid the problem. One suggestion is to perform tests for overflow as a precondition. A simpler and more rapidly implemented solution is to use a type conversion. The check code given above is not eliminated by the optimiser if the char*
type is converted to uintptr_t
or size_t
before performing the operation:
if((uintptr_t)buf+len < (uintptr_t)buf) { … }
According to US-CERT, gcc compilers are affected by this changed behaviour from version 4.2, although von Leitner reported it for version 4.1. Programmers are advised to examine their code for instances of the checks in question and either adapt the checks as described or compile their code with older gcc compilers.
See also:
- gcc silently discards some wraparound checks, US-CERT vulnerability note
- pointer arithmetic overflow handling broken, Felix von Leitner's bug report dated April 2006
(mba)