sbrk() does not set errno on overflow

Message ID 20150519152646.GA2052@rei.suse.de
State Superseded
Headers

Commit Message

Cyril Hrubis May 19, 2015, 3:26 p.m. UTC
  Hi!
I've been looking at LTP test failures on x86_64 and 32bit test binaries
and I've found that testcase for sbrk() fails. What the test does is to
call sbrk() repeatedly until it fails and checks that the return value
is -1 and errno set to ENOMEM.

Now this works fine on x86_64 because we hit ENOMEM from kernel brk()
before address space overflows. But with 32bit binary we hit overflow
check in glibc which does not seem to set errno.

Here is what I would do for a fix, I will create a proper patch with ChangeLog
etc. if this change is OK for glibc.
  

Comments

Andreas Schwab May 19, 2015, 3:47 p.m. UTC | #1
Cyril Hrubis <chrubis@suse.cz> writes:

> diff --git a/misc/sbrk.c b/misc/sbrk.c
> index 87b5472..7ff3921 100644
> --- a/misc/sbrk.c
> +++ b/misc/sbrk.c
> @@ -50,8 +50,10 @@ __sbrk (intptr_t increment)
>    if ((increment > 0
>         ? ((uintptr_t) oldbrk + (uintptr_t) increment < (uintptr_t) oldbrk)
>         : ((uintptr_t) oldbrk < (uintptr_t) -increment))
> -      || __brk (oldbrk + increment) < 0)
> +      || __brk (oldbrk + increment) < 0) {
> +    __set_errno (ENOMEM);
>      return (void *) -1;
> +  }

You should only set errno if __brk wasn't the reason for the error.
Also wrong indentation.

Andreas.
  

Patch

diff --git a/misc/sbrk.c b/misc/sbrk.c
index 87b5472..7ff3921 100644
--- a/misc/sbrk.c
+++ b/misc/sbrk.c
@@ -50,8 +50,10 @@  __sbrk (intptr_t increment)
   if ((increment > 0
        ? ((uintptr_t) oldbrk + (uintptr_t) increment < (uintptr_t) oldbrk)
        : ((uintptr_t) oldbrk < (uintptr_t) -increment))
-      || __brk (oldbrk + increment) < 0)
+      || __brk (oldbrk + increment) < 0) {
+    __set_errno (ENOMEM);
     return (void *) -1;
+  }

   return oldbrk;
 }