ports/163115: [PATCH] devel/glib20: text relocations in libglib-2.0.so.0
Jilles Tjoelker
jilles at stack.nl
Wed Dec 7 21:10:09 UTC 2011
>Number: 163115
>Category: ports
>Synopsis: [PATCH] devel/glib20: text relocations in libglib-2.0.so.0
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-ports-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Dec 07 21:10:08 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator: Jilles Tjoelker
>Release: FreeBSD 8.2-STABLE i386
>Organization:
The FreeBSD Project
>Environment:
FreeBSD 8-stable i386
glib-2.28.8_2
>Description:
The library libglib-2.0.so.0 has text relocations, meaning relocations
in the program code that should be read-only. Text relocations cause
unnecessary load on the VM system and may affect security negatively.
>How-To-Repeat:
The DT_TEXTREL marker is present:
% objdump -p /usr/local/lib/libglib-2.0.so.0|grep TEXTREL
TEXTREL 0x0
The problematic relocations are (on i386):
% objdump -R /usr/local/lib/libglib-2.0.so.0|grep PC32
0007049f R_386_PC32 _g_mem_thread_init_noprivate_nomessage
00070501 R_386_PC32 _g_atomic_thread_init
>Fix:
Because of missing includes, the functions
_g_mem_thread_init_noprivate_nomessage() and _g_atomic_thread_init()
are defined with default visibility, but called as if they have hidden
visibility. This is wrong and I would expect a linker error, but the
linker accepts it anyway and generates a binary that works albeit with
text relocations.
What the linker apparently does is to fulfill both definition and call's
requirements: the definition has default visibility and can therefore be
interposed (via the main executable, LD_PRELOAD or an earlier library),
and the R_386_PC32 call wants to access the function directly rather
than via the PLT (even though an R_386_PC32 relocation pretty much must
be a call or jump instruction that will not see a difference between
direct access and access via the PLT).
For some reason, the linker also does this on amd64, with an
R_X86_64_PC32 relocation, even though the target must be within 2
gigabytes and interposition is therefore unreliable. (Our rtld silently
truncates the offset to 32 bits in this case, so a crash is likely if
the interposing function is too far.)
On some other operating systems (version of binutils?), linking on amd64
fails.
The flag -Bsymbolic-functions, available in more recent binutils and
frequently enabled in some Linux distributions, probably works around
this problem as it disallows interposition when a library calls its own
default-visibility functions, at the cost of giving them different
function pointers.
This code has been reworked in glib 2.30 and I think 2.30 no longer has
the problem. Depending on how long 2.30 takes it may be worth it to fix
2.28.
The below patch, to be put in ports/devel/glib/files/, adds the missing
includes so that the two functions are consistently declared with hidden
visibility.
--- patch-glib_fix_hidden begins here ---
--- glib/gatomic-gcc.c.orig 2011-06-06 01:18:49.000000000 +0200
+++ glib/gatomic-gcc.c 2011-12-07 00:24:48.000000000 +0100
@@ -22,6 +22,8 @@
#include "gatomic.h"
+#include "gthreadprivate.h"
+
gint
g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
gint val)
--- glib/gmem.c.orig 2011-02-10 00:31:42.000000000 +0100
+++ glib/gmem.c 2011-12-07 00:21:38.000000000 +0100
@@ -39,6 +39,7 @@
#include "gbacktrace.h"
#include "gtestutils.h"
#include "gthread.h"
+#include "gthreadprivate.h"
#include "glib_trace.h"
--- patch-glib_fix_hidden ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-ports-bugs
mailing list