Check GOTOFF reloc against protected data on x86

R_386_GOTOFF/R_X86_64_GOTOFF64 relocation shouldn't be used against
protected data symbol on x86 since with copy relocation, address of
protected data defined in the shared library may be external.

This patch will break building shared libraries with protected data
symbols using GCCs older than GCC 5 without the bug fix for

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65248

GCC backport request should be made in the GCC bug report above.

bfd/

	PR ld/pr17709
	* elf32-i386.c (elf_i386_relocate_section): Also check R_386_GOTOFF
	against protected data symbol when building shared library.
	* elf64-x86-64.c (elf_x86_64_relocate_section): Also check
	R_X86_64_GOTOFF64 against protected data symbol when building
	shared library.

ld/testsuite/

	PR ld/pr17709
	* ld-i386/protected6.d: New file.
	* ld-i386/protected6.s: Likewise.
	* ld-x86-64/protected6.d: Likewise.
	* ld-x86-64/protected6.s: Likewise.
	* ld-x86-64/protected7.d: Likewise.
	* ld-x86-64/protected7.s: Likewise.
	* ld-x86-64/protected7a.d: Likewise.
	* ld-x86-64/protected7b.d: Likewise.
This commit is contained in:
H.J. Lu 2015-04-10 14:02:23 -07:00
parent 9ee417720b
commit 3d9499950a
13 changed files with 100 additions and 13 deletions

View File

@ -1,3 +1,12 @@
2015-04-10 H.J. Lu <hongjiu.lu@intel.com>
PR ld/pr17709
* elf32-i386.c (elf_i386_relocate_section): Also check R_386_GOTOFF
against protected data symbol when building shared library.
* elf64-x86-64.c (elf_x86_64_relocate_section): Also check
R_X86_64_GOTOFF64 against protected data symbol when building
shared library.
2015-04-10 H.J. Lu <hongjiu.lu@intel.com>
PR ld/pr15228

View File

@ -3714,10 +3714,10 @@ elf_i386_relocate_section (bfd *output_bfd,
/* Relocation is relative to the start of the global offset
table. */
/* Check to make sure it isn't a protected function symbol
for shared library since it may not be local when used
as function address. We also need to make sure that a
symbol is defined locally. */
/* Check to make sure it isn't a protected function or data
symbol for shared library since it may not be local when
used as function address or with copy relocation. We also
need to make sure that a symbol is defined locally. */
if (info->shared && h)
{
if (!h->def_regular)
@ -3748,12 +3748,15 @@ elf_i386_relocate_section (bfd *output_bfd,
}
else if (!info->executable
&& !SYMBOLIC_BIND (info, h)
&& h->type == STT_FUNC
&& (h->type == STT_FUNC
|| h->type == STT_OBJECT)
&& ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
{
(*_bfd_error_handler)
(_("%B: relocation R_386_GOTOFF against protected function `%s' can not be used when making a shared object"),
input_bfd, h->root.root.string);
(_("%B: relocation R_386_GOTOFF against protected %s `%s' can not be used when making a shared object"),
input_bfd,
h->type == STT_FUNC ? "function" : "data",
h->root.root.string);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}

View File

@ -3955,19 +3955,22 @@ elf_x86_64_relocate_section (bfd *output_bfd,
/* Relocation is relative to the start of the global offset
table. */
/* Check to make sure it isn't a protected function symbol
for shared library since it may not be local when used
as function address. */
/* Check to make sure it isn't a protected function or data
symbol for shared library since it may not be local when
used as function address or with copy relocation. */
if (!info->executable
&& h
&& !SYMBOLIC_BIND (info, h)
&& h->def_regular
&& h->type == STT_FUNC
&& (h->type == STT_FUNC
|| h->type == STT_OBJECT)
&& ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
{
(*_bfd_error_handler)
(_("%B: relocation R_X86_64_GOTOFF64 against protected function `%s' can not be used when making a shared object"),
input_bfd, h->root.root.string);
(_("%B: relocation R_X86_64_GOTOFF64 against protected %s `%s' can not be used when making a shared object"),
input_bfd,
h->type == STT_FUNC ? "function" : "data",
h->root.root.string);
bfd_set_error (bfd_error_bad_value);
return FALSE;
}

View File

@ -1,3 +1,15 @@
2015-04-10 H.J. Lu <hongjiu.lu@intel.com>
PR ld/pr17709
* ld-i386/protected6.d: New file.
* ld-i386/protected6.s: Likewise.
* ld-x86-64/protected6.d: Likewise.
* ld-x86-64/protected6.s: Likewise.
* ld-x86-64/protected7.d: Likewise.
* ld-x86-64/protected7.s: Likewise.
* ld-x86-64/protected7a.d: Likewise.
* ld-x86-64/protected7b.d: Likewise.
2015-04-10 H.J. Lu <hongjiu.lu@intel.com>
PR ld/pr15228

View File

@ -236,6 +236,7 @@ run_dump_test "protected2"
run_dump_test "protected3"
run_dump_test "protected4"
run_dump_test "protected5"
run_dump_test "protected6"
run_dump_test "tlspie1"
run_dump_test "tlspie2"
run_dump_test "nogot1"

View File

@ -0,0 +1,3 @@
#as: --32
#ld: -shared -melf_i386
#error: .*relocation R_386_GOTOFF against protected data `foo' can not be used when making a shared object

View File

@ -0,0 +1,14 @@
.data
.protected foo
.globl foo
.align 4
.type foo, @object
.size foo, 4
foo:
.long 1
.text
.globl bar
.type bar, @function
bar:
movl foo@GOTOFF(%ecx), %eax
.size bar, .-bar

View File

@ -0,0 +1,3 @@
#as: --64
#ld: -shared -melf_x86_64
#error: .*relocation R_X86_64_GOTOFF64 against protected data `foo' can not be used when making a shared object

View File

@ -0,0 +1,14 @@
.protected foo
.globl foo
.data
.align 4
.type foo, @object
.size foo, 4
foo:
.long 1
.text
.globl bar
.type bar, @function
bar:
movabsq $foo@GOTOFF, %rax
.size bar, .-bar

View File

@ -0,0 +1,12 @@
.text
.globl foo
.protected foo
.type foo, @function
foo:
ret
.size foo, .-foo
.globl bar
.type bar, @function
bar:
movabsq $foo@GOTOFF, %rax
.size bar, .-bar

View File

@ -0,0 +1,4 @@
#source: protected7.s
#as: --64
#ld: -shared -melf_x86_64
#error: .*relocation R_X86_64_GOTOFF64 against protected function `foo' can not be used when making a shared object

View File

@ -0,0 +1,6 @@
#source: protected7.s
#as: --64
#ld: -shared -Bsymbolic -melf_x86_64
#readelf: -r
There are no relocations in this file.

View File

@ -218,6 +218,9 @@ run_dump_test "protected3"
run_dump_test "protected3-l1om"
run_dump_test "protected4"
run_dump_test "protected5"
run_dump_test "protected6"
run_dump_test "protected7a"
run_dump_test "protected7b"
run_dump_test "tlsle1"
run_dump_test "tlspie1"
run_dump_test "unique1"