Package: libc6 Version: 2.3.5-9 Severity: normal Tags: patch
When using a kernel with a 64kB page size we noticed a glibc issue where execute permission can be removed from the GOT. Since the GOT needs to be executable we then die (it uses a trick with a blrl instruction in order to find the GOT address). Details of this bug can be found at: http://sources.redhat.com/bugzilla/show_bug.cgi?id=1346 The upstream fix, rediffed and tested against 2.3.5-9 is below. 2005-09-20 Roland McGrath <[EMAIL PROTECTED]> [BZ #1346] * elf/dl-load.c (_dl_map_object_from_fd) [HAVE_Z_RELRO]: Do relro magic on __stack_prot only if [SHARED]. Skip mprotect if __stack_prot lies outside the page-rounded-down relro region. --- elf/dl-load.c~ 2005-12-14 22:27:00.000000000 -0600 +++ elf/dl-load.c 2005-12-14 22:35:59.000000000 -0600 @@ -1314,22 +1314,36 @@ if (__builtin_expect ((stack_flags &~ GL(dl_stack_flags)) & PF_X, 0)) { + if (__builtin_expect (__check_caller (RETURN_ADDRESS (0), allow_ldso), + 0) != 0) + { + errstring = N_("invalid caller"); + goto call_lose; + } + /* The stack is presently not executable, but this module requires that it be executable. We must change the protection of the variable which contains the flags used in the mprotect calls. */ -#ifdef HAVE_Z_RELRO +#if defined HAVE_Z_RELRO && defined SHARED if (mode & __RTLD_DLOPEN) { - uintptr_t p = ((uintptr_t) &__stack_prot) & ~(GLRO(dl_pagesize) - 1); - size_t s = (uintptr_t) &__stack_prot - p + sizeof (int); + const uintptr_t p = (uintptr_t) &__stack_prot & -GLRO(dl_pagesize); + const size_t s = (uintptr_t) (&__stack_prot + 1) - p; - __mprotect ((void *) p, s, PROT_READ|PROT_WRITE); - if (__builtin_expect (__check_caller (RETURN_ADDRESS (0), - allow_ldso|allow_libc) == 0, - 0)) + struct link_map *const m = &GL(dl_rtld_map); + const uintptr_t relro_end = ((m->l_addr + m->l_relro_addr + + m->l_relro_size) + & -GLRO(dl_pagesize)); + if (__builtin_expect (p + s <= relro_end, 1)) + { + /* The variable lies in the region protected by RELRO. */ + __mprotect ((void *) p, s, PROT_READ|PROT_WRITE); + __stack_prot |= PROT_READ|PROT_WRITE|PROT_EXEC; + __mprotect ((void *) p, s, PROT_READ); + } + else __stack_prot |= PROT_READ|PROT_WRITE|PROT_EXEC; - __mprotect ((void *) p, s, PROT_READ); } else #endif -- System Information: Debian Release: testing/unstable APT prefers unstable APT policy: (500, 'unstable') Architecture: powerpc (ppc) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.15-rc6-gdf7addbb Locale: LANG=en_AU, LC_CTYPE=en_AU (charmap=ISO-8859-1) -- no debconf information -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]