manpagez: man pages & more
info autoconf
Home | html | info | man

File: autoconf.info,  Node: Signed Overflow Examples,  Next: Optimization and Wraparound,  Prev: Integer Overflow Basics,  Up: Integer Overflow

13.2.2 Examples of Code Assuming Wraparound Overflow
----------------------------------------------------

There was long a tension between what the C standard requires for signed
integer overflow, and what traditional C programs commonly assumed.  The
standard allows aggressive optimizations based on assumptions that
overflow never occurs, but traditionally many C programs relied on
overflow wrapping around.  Although these programs did not conform to
the standard, they formerly worked in practice because traditionally
compilers did not optimize in such a way that would break the programs.
Nowadays, though, compilers do perform these optimizations, so portable
programs can no longer assume reliable wraparound on signed integer
overflow.

   The C Standard says that if a program has signed integer overflow its
behavior is undefined, and the undefined behavior can even precede the
overflow.  To take an extreme example:

     if (password == expected_password)
       allow_superuser_privileges ();
     else if (counter++ == INT_MAX)
       abort ();
     else
       printf ("%d password mismatches\n", counter);

If the ‘int’ variable ‘counter’ equals ‘INT_MAX’, ‘counter++’ must
overflow and the behavior is undefined, so the C standard allows the
compiler to optimize away the test against ‘INT_MAX’ and the ‘abort’
call.  Worse, if an earlier bug in the program lets the compiler deduce
that ‘counter == INT_MAX’ or that ‘counter’ previously overflowed, the C
standard allows the compiler to optimize away the password test and
generate code that allows superuser privileges unconditionally.

   Here is an example derived from the 7th Edition Unix implementation
of ‘atoi’ (1979-01-10):

     char *p;
     int f, n;
     ...
     while (*p >= '0' && *p <= '9')
       n = n * 10 + *p++ - '0';
     return (f ? -n : n);

Even if the input string is in range, on most modern machines this has
signed overflow when computing the most negative integer (the ‘-n’
overflows) or a value near an extreme integer (the ‘+’ overflows).

   Here is another example, derived from the 7th Edition implementation
of ‘rand’ (1979-01-10).  Here the programmer expects both multiplication
and addition to wrap on overflow:

     static long int randx = 1;
     ...
     randx = randx * 1103515245 + 12345;
     return (randx >> 16) & 077777;

   In the following example, derived from the GNU C Library 2.15
implementation of ‘mktime’ (2012-03-21), the code assumes wraparound
arithmetic in ‘+’ to detect signed overflow:

     time_t t, t1, t2;
     int sec_requested, sec_adjustment;
     ...
     t1 = t + sec_requested;
     t2 = t1 + sec_adjustment;
     if (((t1 < t) != (sec_requested < 0))
         | ((t2 < t1) != (sec_adjustment < 0)))
       return -1;

   Although some of these examples will likely behave as if signed
integer overflow wraps around reliably, other examples are likely to
misbehave when optimization is enabled.  All these examples should be
avoided in portable code because signed integer overflow is not reliable
on modern systems, and it's not worth worrying about which of these
examples happen to work on most platforms and which do not.

© manpagez.com 2000-2024
Individual documents may contain additional copyright information.