[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [oss-security] Controversy and exploitability of gcc issue 30475 |assert(int+100 > int)|




> On 8 Nov 2019, at 08:03, Georgi Guninski <gguninski AT gmail.com> wrote:
> 
> Controversy and exploitability of gcc issue 30475 |assert(int+100 > int)|
> 
> There is heated discussion on gcc's bugzilla starting from 2007:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=30475
> and clang is also affected, depending on optimization flags.
> 
> poc is the program at end.
> 
> gcc with all optimization flags optimizes away |assert(a+100 > a)|
> even if there is no integer overflow, only signed overflow.
> 
> clang fires the assertion with -O0, but also optimizes it away
> with -O3
> 
> The formal verifier CBMC fires the assertion, which might of
> interest about formally verified programs.
> 
> Signed integer arithmetic is commonly used even without integer
> overflows.
> 
> Could this compiler issue be security problem?
> 
> Any workarounds?


It's not really a compiler issue: the PoC is dependent on undefined behaviour and the compiler is free to do whatever it wants with undefined behaviour.  Many, many years ago I chatted with my then supervisor about having a compiler do interesting things with undefined behaviour for example, just replace that assert to print this to stdout:

	The Tao is forever undefined.
	Small though it is in the unformed state, it cannot be grasped.
	If kings and lords could harness it,
	The ten thousand things would come together
	And gentle rain fall.
	Men would need no more instruction and all things would take their course.
	Once the whole is divided, the parts need names.
	There are already enough names.
	One must know when to stop.
	Knowing when to stop averts trouble.
	Tao in the world is like a river flowing home to the sea.

Seriously, though, there are a lot of programs out there that *depend* on undefined behaviour being compiled in a particular way.   Sooner or later those programs mysteriously fail and that might lead to a security issue or just inexplicable behaviour.

In this particular case, the assert() will always trigger if the assert is on "a > INT_MAX-100" because that is well defined.   Does ubsan catch this issue?

jch

> 
> ===poc===
> #include <assert.h>
> 
> int foo(int a) {
>  assert(a+100 > a);
>  printf("%d %d\n",a+100,a);
>  return a;
> }
> 
> int main() {
>  foo(100);
>  foo(0x7fffffff);
> }
> =========
> 
> 
> CV:    https://j.ludost.net/resumegg.pdf
> site:  http://www.guninski.com
> blog:  https://j.ludost.net/blog

Attachment: signature.asc
Description: Message signed with OpenPGP