Bug 1659276 - glibc: Test suite failure: malloc/tst-malloc-usable-tunables (ppc64le)
Summary: glibc: Test suite failure: malloc/tst-malloc-usable-tunables (ppc64le)
Keywords:
Status: CLOSED UPSTREAM
Alias: None
Product: Fedora
Classification: Fedora
Component: glibc
Version: 29
Hardware: ppc64le
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Carlos O'Donell
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2018-12-14 00:28 UTC by Carlos O'Donell
Modified: 2019-10-01 13:45 UTC (History)
9 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2019-10-01 13:45:26 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Bugzilla 1749633 0 unspecified CLOSED kernel: brk can grow the heap into the area reserved for the stack 2023-08-08 02:49:41 UTC
Sourceware 25035 0 P2 NEW sbrk() failure handled poorly in tunables_strdup 2019-12-16 19:47:54 UTC

Description Carlos O'Donell 2018-12-14 00:28:06 UTC
Only on ppc64le.

The tst-malloc-usable-tunables test failed in glibc-2.28-26.fc29.

FAIL: malloc/tst-malloc-usable-tunables

=====FAIL: malloc/tst-malloc-usable-tunables.out=====
malloc_usable_size: expected 7 but got 24
=====FAIL: malloc/tst-malloc-usable-tunables.test-result=====
FAIL: malloc/tst-malloc-usable-tunables
original exit status 1

This looks like the hooks were not installed and we did not get the real usable size of the chunk.

Comment 1 DJ Delorie 2019-09-25 20:07:07 UTC
I did an RCA on this for an internal bug reporting the same issue, I'll paste the result here for posterity...

tl;dr it's address space randomization, but glibc should handle it better...

A normal run of my instrumented libc.so looks like this:

i 36 in 'GLIBC_TUNABLES=glibc.malloc.check=3' out 7fffc2120000 0
sbrk(0) 7fffc2120024
7fff8b0f0000-7fff8b110000 r-xp 00000000 00:00 0                          [vdso]
7fff8b110000-7fff8b140000 r-xp 00000000 fd:00 102121442                  /root/rpmbuild/BUILD/glibc-2.28/build-ppc64le-redhat-linux/elf/ld.so
7fff8b140000-7fff8b160000 rw-p 00020000 fd:00 102121442                  /root/rpmbuild/BUILD/glibc-2.28/build-ppc64le-redhat-linux/elf/ld.so
7fffc2120000-7fffc2130000 rw-p 00000000 00:00 0                          [heap]
7fffe7de0000-7fffe7e10000 rw-p 00000000 00:00 0                          [stack]
ne1
ne1
dj: test malloc
dj: ptmalloc_init
dj: ptmalloc GLIBC_TUNABLES = 'glibc.malloc.check=3'
dj: tune mallopt 3

The first part is in dl-tunables.c:tunables_strdup().  __sbrk(36)
returns something reasonable in the heap, "ne1" means new_env is set
in __tunables_init, and the dj: lines show that we initialize the
tunable correctly.


i 36 in 'GLIBC_TUNABLES=glibc.malloc.check=3' out ffffffffffffffff 12
sbrk(0) 7fffc18d0000
7fffaf0d0000-7fffaf0f0000 r-xp 00000000 00:00 0                          [vdso]
7fffaf0f0000-7fffaf120000 r-xp 00000000 fd:00 102121442                  /root/rpmbuild/BUILD/glibc-2.28/build-ppc64le-redhat-linux/elf/ld.so
7fffaf120000-7fffaf140000 rw-p 00020000 fd:00 102121442                  /root/rpmbuild/BUILD/glibc-2.28/build-ppc64le-redhat-linux/elf/ld.so
7fffc2540000-7fffc2570000 rw-p 00000000 00:00 0                          [stack]
strdup NULL
ne0
ne0
dj: test malloc
dj: ptmalloc_init
dj: ptmalloc GLIBC_TUNABLES = '(null)'
malloc_usable_size: expected 7 but got 24

In this case, __sbrk(36) returns -1.  I dumped the process map at that
point.  Note there is no [heap] map.  I don't know if it's the kernel
or libc that has to set that, but it *only* happens if
/proc/sys/kernel/randomize_va_space is set to 2

randomize_va_space:
0: disabled
1: Conservative: Shared libraries and PIE binaries are randomized.
2: Conservative and start of brk area is randomized, too

Yay, start of brk area is randomized - and sometimes that's fatal.


Moving on, though... the sbrk() fails, NULL is returned, and that
"string" is injected into the environ[] list, effectively removing
that variable - and all variables following it - from the environment.

	  if (new_env != NULL)
	    parse_tunables (new_env + len + 1, envval);
	  /* Put in the updated envval.  */
	  *prev_envp = new_env;

We shouldn't put new_env into *prev_envp if new_env is NULL.

But that won't fix the randomization problem; sbrk still fails and
tunables are still not parsed.

More:  I was able to strace one of the failures:

execve("./elf/ld64.so.2", ["./elf/ld64.so.2", "--library-path", ".:./math:./elf:./dlfcn:./nss:./n"..., "malloc/tst-malloc-usable-tunable"...], 0x10003ae52c0 /* 44 vars */) = 0
brk(NULL)                               = 0x7fffcaa00000
brk(0x7fffcaa00024)                     = 0x7fffcaa00000


Full reproduction steps:
* Get the glibc SPRM and install it; rpmbuild -ba glibc.spec
* cd rpmbuild/BUILD/glibc*/build*
* while GLIBC_TUNABLES=glibc.malloc.check=3 strace -f /bin/bash ./testrun.sh malloc/tst-malloc-usable-tunables; do echo; done

Comment 2 Carlos O'Donell 2019-10-01 13:45:26 UTC
We are not going to fix this in Fedora, this needs to be fixed in upstream via:
https://sourceware.org/bugzilla/show_bug.cgi?id=25035

The kernel also needs to fix this issue, and we've filed kernel bugs for that.


Note You need to log in before you can comment on or make changes to this bug.