public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Silent stack-heap collision under GNU/Linux
@ 2014-07-20 17:49 Vincent Lefevre
  2014-07-20 19:04 ` Ian Lance Taylor
  2014-07-21  9:44 ` Florian Weimer
  0 siblings, 2 replies; 4+ messages in thread
From: Vincent Lefevre @ 2014-07-20 17:49 UTC (permalink / raw)
  To: gcc-help

It appears that GCC can generate code that yields silent stack-heap
collision under GNU/Linux. I mean, the program doesn't crash (at least
not immediately), the memory just gets corrupted. At the same time,
this overrides the stack-size limit defined at the kernel level
(getrlimit system call / RLIMIT_STACK) because the kernel has no
chance to detect the collision (no page fault); thus this limit
doesn't protect the user, and the problem seems to be on GCC's side.

Why aren't such collisions detected by default?

How can one tell GCC to detect them?

Here's a test case:

------------------------------------------------------------------------
#include <stdio.h>

static char a = 0;
static unsigned long pa, pb, pc;

#define GETADDR(V) \
  do { p##V = (unsigned long) &V; printf ("&" #V " = %016lx\n", p##V); } \
  while (0)

void foo (unsigned long s)
{
  char c[s];

  GETADDR(c);
  if (pa >= pc)
    c[pa - pc] = 1;
  else
    printf ("Cannot test.\n");
}

int main (int argc, char **argv)
{
  char b;

  GETADDR(a);
  GETADDR(b);

  printf ("a = %d\n", a);
  if (pb > pa)
    foo (pb - pa);
  else
    printf ("Cannot test.\n");
  printf ("a = %d\n", a);

  return 0;
}
------------------------------------------------------------------------

I get something like:

&a = 0000000000600b20
&b = 00007fffbfea7d2f
a = 0
&c = 0000000000600ac0
a = 1

Same problem with the 32-bit ABI (-m32).

With GCC 4.9.1 (Debian/unstable), the program terminates successfully.
With the 4.10.0 snapshot, I also get a segmentation fault at the end,
but that's too late.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Silent stack-heap collision under GNU/Linux
  2014-07-20 17:49 Silent stack-heap collision under GNU/Linux Vincent Lefevre
@ 2014-07-20 19:04 ` Ian Lance Taylor
  2014-07-20 20:37   ` Vincent Lefevre
  2014-07-21  9:44 ` Florian Weimer
  1 sibling, 1 reply; 4+ messages in thread
From: Ian Lance Taylor @ 2014-07-20 19:04 UTC (permalink / raw)
  To: gcc-help

On Sun, Jul 20, 2014 at 10:49 AM, Vincent Lefevre
<vincent+gcc@vinc17.org> wrote:
> It appears that GCC can generate code that yields silent stack-heap
> collision under GNU/Linux. I mean, the program doesn't crash (at least
> not immediately), the memory just gets corrupted. At the same time,
> this overrides the stack-size limit defined at the kernel level
> (getrlimit system call / RLIMIT_STACK) because the kernel has no
> chance to detect the collision (no page fault); thus this limit
> doesn't protect the user, and the problem seems to be on GCC's side.
>
> Why aren't such collisions detected by default?

Because it's expensive, and GCC takes the attitude that the C language
comes without safety guards.


> How can one tell GCC to detect them?

Use the -fstack-check option.  Or -fsanitize=address.  Or if you don't
need variable length arrays at all, you could use -Werror=vla.

Ian

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Silent stack-heap collision under GNU/Linux
  2014-07-20 19:04 ` Ian Lance Taylor
@ 2014-07-20 20:37   ` Vincent Lefevre
  0 siblings, 0 replies; 4+ messages in thread
From: Vincent Lefevre @ 2014-07-20 20:37 UTC (permalink / raw)
  To: gcc-help

On 2014-07-20 12:04:43 -0700, Ian Lance Taylor wrote:
> On Sun, Jul 20, 2014 at 10:49 AM, Vincent Lefevre
> <vincent+gcc@vinc17.org> wrote:
> > It appears that GCC can generate code that yields silent stack-heap
> > collision under GNU/Linux. I mean, the program doesn't crash (at least
> > not immediately), the memory just gets corrupted. At the same time,
> > this overrides the stack-size limit defined at the kernel level
> > (getrlimit system call / RLIMIT_STACK) because the kernel has no
> > chance to detect the collision (no page fault); thus this limit
> > doesn't protect the user, and the problem seems to be on GCC's side.
> >
> > Why aren't such collisions detected by default?
> 
> Because it's expensive,
[...]

Really? This takes only a few instructions, doesn't it? And AFAIK,
the detection is needed only when the stack pointer decrement is
important (the problem occurs only when unmapped memory after the
stack is skipped). In most cases, VLA's are not used and GCC should
be able to determine an upper bound on the stack pointer decrement,
thus avoiding generating this detection on functions that don't need
it.

> > How can one tell GCC to detect them?
> 
> Use the -fstack-check option.
[...]

Thanks, I hadn't tried this one.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Silent stack-heap collision under GNU/Linux
  2014-07-20 17:49 Silent stack-heap collision under GNU/Linux Vincent Lefevre
  2014-07-20 19:04 ` Ian Lance Taylor
@ 2014-07-21  9:44 ` Florian Weimer
  1 sibling, 0 replies; 4+ messages in thread
From: Florian Weimer @ 2014-07-21  9:44 UTC (permalink / raw)
  To: Vincent Lefevre; +Cc: gcc-help

On 07/20/2014 07:49 PM, Vincent Lefevre wrote:
> It appears that GCC can generate code that yields silent stack-heap
> collision under GNU/Linux. I mean, the program doesn't crash (at least
> not immediately), the memory just gets corrupted. At the same time,
> this overrides the stack-size limit defined at the kernel level
> (getrlimit system call / RLIMIT_STACK) because the kernel has no
> chance to detect the collision (no page fault); thus this limit
> doesn't protect the user, and the problem seems to be on GCC's side.
>
> Why aren't such collisions detected by default?

You can try -fstack-check, but it instruments functions unnecessarily.

-- 
Florian Weimer / Red Hat Product Security

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-07-21  9:44 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-20 17:49 Silent stack-heap collision under GNU/Linux Vincent Lefevre
2014-07-20 19:04 ` Ian Lance Taylor
2014-07-20 20:37   ` Vincent Lefevre
2014-07-21  9:44 ` Florian Weimer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).