Bug 11929

Summary: glibc-2.12: static binaries: __getpagesize: Assertion `_rtld_global_ro._dl_pagesize != 0'
Product: glibc Reporter: Mike Frysinger <vapier>
Component: libcAssignee: Ulrich Drepper <drepper.fsp>
Status: RESOLVED FIXED    
Severity: normal CC: allan, glibc-bugs, lool, me, toolchain
Priority: P2 Flags: fweimer: security-
Version: 2.12   
Target Milestone: ---   
Host: x86_64-linux-gnu Target:
Build: Last reconfirmed:
Attachments: glibc-2.12-static-glro-init.patch

Description Mike Frysinger 2010-08-19 22:41:04 UTC
as first reported here:
    http://thread.gmane.org/gmane.comp.lib.glibc.user/579

building programs statically that require shared nss libraries at runtime will
often crash with the assert '_rtld_global_ro._dl_pagesize != 0'

this is because after a recent change to __getpagesize(), GLRO(dl_pagesize) is
required to be set.  but that is only done at app init, and shared libraries
dlopened at runtime by static apps dont have their GLRO() state initialized from
the linux auxvec.

ia64/mips have long had similar behavior with their __getpagesize(), but they
have a DL_STATIC_INIT hook to sync some of the static GLRO() fields to the
dynamic GLRO() fields.  now that common linux code requires GLRO(dl_pagesize) to
be set, common linux code now needs that DL_STATIC_INIT hook.

attached patch takes the ia64 logic and promotes it to common code.
Comment 1 Mike Frysinger 2010-08-19 22:41:51 UTC
Created attachment 4941 [details]
glibc-2.12-static-glro-init.patch
Comment 2 Allan McRae 2010-10-25 16:10:11 UTC
This patch causes some issues when static linking.  e.g.:

#include <iconv.h>
#include <stdio.h>
#include <errno.h>
int main () {
  iconv_t x;
  x = iconv_open ("UTF-8", "UTF-32LE");
  printf ("%d\n", errno == EINVAL);
  return 0;
}

The iconv_open fails when compiled with -static.  Using the workaround in sysdeps/unix/sysv/linux/getpagesize.c from Fedora git "fixes" the issue:

-#ifdef __ASSUME_AT_PAGESIZE
+#if 0 && defined __ASSUME_AT_PAGESIZE
Comment 3 Loïc Minier 2010-11-11 14:57:00 UTC
Allan, is the iconv issue a new one?  Your testcase fails for me even when Mike's patch isn't applied; I get an assertion failure "_rtld_global_ro._dl_pagesize != 0".

What failure do you get?  Could you break in __getpagesize() and see what pagesize you get in the first (static libc.a copy) and second (lib.so) hits?
Comment 4 Allan McRae 2010-11-11 15:22:46 UTC
Yes...  it is not surprising that you run into the initial bug when not applying the patch!

The point I was making is that Fedora's hack fix fixes both the "_dl_pagesize" issue and the "iconv" one that I pointed out.  That leads me to suspect that some part of the initialisation of static apps is still incomplete after the application of the proposed patch.  And given that changing on #ifdef fixes both, these issues were probably introduced at the same time.
Comment 5 Loïc Minier 2010-11-11 15:32:45 UTC
Sorry, wasn't clear: I did not know whether you iconv issue was there before the patch, and when reading your first comment, I thought it was a rebuttal for Mike's patch, but I wanted to confirm that Mike's patch was an immediate net win (moving arch-specific code to common code and fixing at least one class of issues), even if it doesn't fix all instances of this class of bugs.

Hope this makes more sense now  :)

I understand that the Fedora change is just meant to be a workaround rather than a fix?  There might be other random issues if the vdso isn't setup properly in the static+dynamic case, so it would be best to init libc properly in this case rather than fix just the getpagesize() issue?
Comment 6 Allan McRae 2010-11-12 00:13:28 UTC
Yes, the patch is an improvement but it either:
1) is incomplete
2) introduces a new big (with iconv test case)

I am leaning towards #1, but have not had time to investigate further.
Comment 7 Mike Frysinger 2010-11-22 18:57:59 UTC
the iconv code calls the gconv code which attempts to dynamically load shared objects from /usr/lib64/gconv/.  i havent dug past that so far, but it seems to boil down to the same issue -- dlopening shared objects from static objects is broken.
Comment 8 Allan McRae 2011-12-27 05:49:57 UTC
From some quick testing, it appears this bug is fixed in glibc-2.15.  Possibly by commit 02d46fc4.
Comment 9 Ulrich Drepper 2012-01-09 01:40:26 UTC
I went ahead and marked the change as the fix.