Bug 9914 - possible signed integer overflow in libio/iogetdelim.c
Summary: possible signed integer overflow in libio/iogetdelim.c
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: stdio (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-03-01 17:36 UTC by Aurelien Jarno
Modified: 2014-07-01 20:44 UTC (History)
5 users (show)

See Also:
Host: x86_64-unknown-linux-gnu
Target: x86_64-unknown-linux-gnu
Build: x86_64-unknown-linux-gnu
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Aurelien Jarno 2009-03-01 17:36:05 UTC
glibc does not compile at -O0 and -fstrict-overflow is enabled starting at -O1,
meaning that -fstrict-overflow is always enabled.

As a result, this code from libio/iogetdelim.c is wrong as gcc is free to
optimize it out in case of overflow:

  if (__builtin_expect (cur_len + len + 1 < 0, 0))
    {
      __set_errno (EOVERFLOW);
      result = -1;
      goto unlock_return;
    }
Comment 1 Rich Felker 2011-10-24 15:18:34 UTC
Ping. This bug seems valid and has not been fixed. The fix is easy; change the condition to (len >= SSIZE_MAX - cur_len)
Comment 2 Ulrich Drepper 2011-10-29 20:33:41 UTC
Wrong, gcc cannot and does not optimize the code away.  If it does it's  a compiler problem.
Comment 3 Jakub Jelinek 2011-10-29 20:43:14 UTC
If it is testing whether cur_len + len + 1 overflowed from positive into negative, then it is undefined behavior, because all the additions are performed in signed _IO_ssize_t.
Comment 4 Ulrich Drepper 2011-10-29 21:17:08 UTC
(In reply to comment #3)
> If it is testing whether cur_len + len + 1 overflowed from positive into
> negative, then it is undefined behavior, because all the additions are
> performed in signed _IO_ssize_t.

The compiler cannot know that the variables are not negative.  Therefore the test has to be emitted.
Comment 5 Rich Felker 2011-10-29 21:19:49 UTC
Whether gcc optimizes this away probably depends on the compiler version and
options. I would have to read the code in greater detail to claim that this is definitely the case, but it's likely that it's provable that cur_len and len are always non-negative. Even if not, the code is invoking undefined behavior, so there are other reasons the test could fail to work as expected. I already submitted a fix; please apply or write your own better fix if you prefer.
Comment 6 Ulrich Drepper 2011-10-29 21:37:11 UTC
Stop wasting people's time, there is nothing wrong.
Comment 7 Dmitry V. Levin 2011-10-29 22:11:43 UTC
(In reply to comment #4)
> The compiler cannot know that the variables are not negative.  Therefore the
> test has to be emitted.

If a human can know the fact that these variables are not negative, then a smart compiler also can deduce this fact.
Comment 8 Rich Felker 2011-10-30 05:37:52 UTC
I think it's going to take someone finding a version of gcc that can make the optimization, and then publishing an attack that results in memory corruption and possibly privilege elevation, to break through the brick wall known as Drepper's ego and get this bug fixed...
Comment 9 Joseph Myers 2012-02-21 01:29:46 UTC
FWIW I think we should fix signed integer overflows found in the code even if we do not have any case where they cause problems in practice.
Comment 10 Rich Felker 2012-03-17 20:34:55 UTC
Ping. Has this been fixed?
Comment 11 Joseph Myers 2012-03-18 14:22:11 UTC
From source inspection it appears this issue is still present, and as per my previous comment I think we should fix it.
Comment 12 Joseph Myers 2012-09-04 11:27:02 UTC
Fixed for 2.17 by:

commit 60160d83a09c659d8d9338b210ff92be77cc87d5
Author: Joseph Myers <joseph@codesourcery.com>
Date:   Tue Sep 4 11:24:43 2012 +0000

    Fix iogetdelim.c (latent) integer overflow (bug 9914).