[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#853213: make: leaks RLIMIT_STACK=unlimited causing FTBFS of openjdk-8 on mips



Package: make
Version: 4.1-9
Severity: important
Control: tags -1 patch fixed-upstream
Control: forwarded -1 http://savannah.gnu.org/bugs/?48009
X-Debbugs-CC: debian-mips@lists.debian.org, openjdk@lists.launchpad.net

Hi,

Before discussing the bug in make, I will describe what the original bug
in OpenJDK was (skip if you want)...

OpenJDK is a relatively unusual program in that it attempts to allocate
a very large (depending on options) amount of contiguous memory on
startup to contain the heap, and then it manages it internally. On MIPS,
the parts of the OpenJDK build system which invoke Java allocate 1.1 MB
of memory.

On MIPS, only 2GB of the virtual address space can be used by user-mode
applications. This means that if some memory has already been allocated
near the middle, the 1.1G allocation will fail. The kernel decides two
important addresses which controls a process's address space:
- The address the executable is loaded at.
- The address the first mmap(NULL) is allocated at.

For ET_EXEC files, the address the executable is loaded at is fixed at
compile time by ld, but for ET_DYN (ie -fPIE) executables the kernel
loads it at ELF_ET_DYN_BASE (+ some random offset if ASLR is enabled).
On MIPS, ELF_ET_DYN_BASE = 2/3*2GB (around 0x55550000). Also note that
this behavior changed after linux 4.1 by d1fd836dcf00 ("mm: split ET_DYN
ASLR from mmap ASLR"). Before that commit, ET_DYN files were treated
like mmaps.

Usually the first mmap is located just underneath the stack of the main
thread. However, a legacy layout can be used where the mmap base is
allocated at TASK_UNMAPPED_BASE (1/3*2GB = around 0x2AAA0000). This
legacy layout is used if RLIMIT_STACK = unlimited.

The problem is that if both of these layouts are used (linux >= 4.1,
java compiled with -fPIE, and RLIMIT_STACK = unlimited) then the address
space will look like this:
 0x2AAA0000 = ld.so (first mmap)
 ....       = Other libs / mmaps / vdso
 0x55550000 = java
 ....       = brk heap
 0x7Fxxxxxx = Main thread stack

There is now no contiguous 1.1GB region of memory to allocate Java's heap.

======

This upstream bug in make is this:
http://savannah.gnu.org/bugs/?48009

Make calls setrlimit to increase the stack limit to unlimited because it
uses a lot of stack space. Currently make "leaks" this ulimited stack
size to child processes of make re-execs itself for some reason (see the
bug report). This causes the above FTBFS in OpenJDK on MIPS.

It is already fixed upstream in 4.2.1 here:
http://git.savannah.gnu.org/cgit/make.git/commit/?id=
a3d8c086d54c112fecfa2b9026a32a14f741f5f5

I have attached the upstream patch. Please consider applying this for
stretch.

Thanks,
James
From a3d8c086d54c112fecfa2b9026a32a14f741f5f5 Mon Sep 17 00:00:00 2001
From: Jeremy Devenport <jeremy.devenport@gmail.com>
Date: Tue, 31 May 2016 03:09:24 -0400
Subject: [PATCH] * main.c (main): [SV 48009] Reset stack limit for make
 re-exec.

Copyright-paperwork-exempt: yes
---
 main.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/main.c b/main.c
index e606488..fa8045f 100644
--- a/main.c
+++ b/main.c
@@ -2454,6 +2454,11 @@ main (int argc, char **argv, char **envp)
             exit (WIFEXITED(r) ? WEXITSTATUS(r) : EXIT_FAILURE);
           }
 #else
+#ifdef SET_STACK_SIZE
+          /* Reset limits, if necessary.  */
+          if (stack_limit.rlim_cur)
+            setrlimit (RLIMIT_STACK, &stack_limit);
+#endif
           exec_command ((char **)nargv, environ);
 #endif
           free (aargv);
-- 
2.7.4


Attachment: signature.asc
Description: OpenPGP digital signature


Reply to: