Bug 21997 - GNU_PROPERTY_NO_COPY_ON_PROTECTED is ignored by linker
Summary: GNU_PROPERTY_NO_COPY_ON_PROTECTED is ignored by linker
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.30
: P2 normal
Target Milestone: 2.30
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-08-23 19:04 UTC by H.J. Lu
Modified: 2017-08-27 02:27 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2017-08-23 19:04:36 UTC
When GNU_PROPERTY_NO_COPY_ON_PROTECTED is set on a shared object,
linker shouldn't generate copy relocation on protected symbol defined
in such shared object:

[hjl@gnu-6 protected-3]$ cat foo.c
 __attribute__ ((visibility ("protected")))
int protected = 1;

int
get_protected ()
{
  return protected;
}

int *
get_protected_p ()
{
  return &protected;
}
[hjl@gnu-6 protected-3]$ cat shared.S
	.section ".note.gnu.property", "a"
	.p2align 3
	.long 1f - 0f		/* name length.  */
	.long 3f - 2f		/* data length.  */
	/* NT_GNU_PROPERTY_TYPE_0 */
	.long 5			/* note type.  */
0:	.asciz "GNU"		/* vendor name.  */
1:
	.p2align 3
2:
	/* GNU_PROPERTY_NO_COPY_ON_PROTECTED */
	.long 2			/* pr_type.  */
	.long 0			/* pr_datasz.  */
	.p2align 3
3:
[hjl@gnu-6 protected-3]$ cat main.c
#include <stdlib.h>

extern int protected;
extern int get_protected (void);
extern int* get_protected_p (void);

int main()
{

  if (protected != get_protected ())
    abort ();

  if (&protected != get_protected_p ())
    abort ();

  return 0;
}
[hjl@gnu-6 protected-3]$ make
gcc -B./  -O -c main.c
gcc -B./     -c -o shared.o shared.S
gcc -B./  -O -fPIE -c foo.c
./ld -shared  -o libfoo.so shared.o foo.o
gcc -B./   -o foo main.o libfoo.so -Wl,-rpath,.
for f in foo; do echo "Running: $f"; ./$f; \
  if [ $? != 0 ]; then echo Failed; fi; done
Running: foo
/bin/sh: line 1: 28249 Aborted                 ./$f
Failed
[hjl@gnu-6 protected-3]$
Comment 1 Sourceware Commits 2017-08-27 02:27:18 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a5b4ee9451dc9ffb6aa29376fc03943c53c6da0d

commit a5b4ee9451dc9ffb6aa29376fc03943c53c6da0d
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sat Aug 26 19:22:26 2017 -0700

    Disallow copy relocation against protected data symbol
    
    We shpouldn't generate copy relocation to resolve reference to protected
    data symbol defined in shared object with the NO_COPY_ON_PROTECTED
    property.  This patch adds a bit to elf_obj_tdata as well as
    elf_i386_link_hash_entry and elf_x86_64_link_hash_entry to track the bfd
    with the NO_COPY_ON_PROTECTED property as well as protected symbol
    defined in shared object.  extern_protected_data is set to FALSE if any
    input relocatable file contains the NO_COPY_ON_PROTECTED property.
    
    bfd/
    
    	PR ld/21997
    	* elf-bfd.h (elf_obj_tdata): Use ENUM_BITFIELD on object_id,
    	dyn_lib_class and has_gnu_symbols.  Change bad_symtab to bitfield.
    	Add a has_no_copy_on_protected bitfield.
    	(elf_has_no_copy_on_protected): New.
    	* elf-properties.c (_bfd_elf_parse_gnu_properties): Set
    	elf_has_no_copy_on_protected for GNU_PROPERTY_NO_COPY_ON_PROTECTED.
    	(elf_merge_gnu_property_list): Likewise.
    	(_bfd_elf_link_setup_gnu_properties): Set extern_protected_data
    	to FALSE for elf_has_no_copy_on_protected.
    	* elf32-i386.c (SYMBOL_NO_COPYRELOC): New.
    	(elf_i386_link_hash_entry): Add def_protected.
    	(elf_i386_adjust_dynamic_symbol): Also check SYMBOL_NO_COPYRELOC
    	when checking info->nocopyreloc.
    	(elf_i386_link_setup_gnu_properties): Don't set
    	extern_protected_data here.
    	(elf_i386_merge_symbol_attribute): New function.
    	(elf_backend_merge_symbol_attribute): New.
    	* elf64-x86-64.c (SYMBOL_NO_COPYRELOC): New.
    	(elf_x86_64_link_hash_entry): Add def_protected.
    	(elf_x86_64_need_pic): Report protected symbol for def_protected.
    	(elf_x86_64_adjust_dynamic_symbol): Also check SYMBOL_NO_COPYRELOC
    	when checking info->nocopyreloc.
    	(elf_x86_64_relocate_section): Also check for R_X86_64_PC32
    	relocation run-time overflow and unresolvable R_X86_64_32S
    	relocation against protected data symbol defined in shared object
    	with GNU_PROPERTY_NO_COPY_ON_PROTECTED.
    	(elf_x86_64_link_setup_gnu_properties): Don't set
    	extern_protected_data here.
    	(elf_x86_64_merge_symbol_attribute): New function.
    	(elf_backend_merge_symbol_attribute): New.
    
    ld/
    
    	PR ld/21997
    	* testsuite/ld-i386/i386.exp: Run PR ld/21997 tests.
    	* testsuite/ld-x86-64/x86-64.exp: Likewise.
    	* testsuite/ld-i386/pr21997-1a.S: New file.
    	* testsuite/ld-i386/pr21997-1b.c: Likewise.
    	* testsuite/ld-i386/pr21997-1c.S: Likewise.
    	* testsuite/ld-x86-64/pr21997-1a.S: Likewise.
    	* testsuite/ld-x86-64/pr21997-1a.err: Likewise.
    	* testsuite/ld-x86-64/pr21997-1b.c: Likewise.
    	* testsuite/ld-x86-64/pr21997-1b.err: Likewise.
    	* testsuite/ld-x86-64/pr21997-1c.c: Likewise.
Comment 2 H.J. Lu 2017-08-27 02:27:38 UTC
Fixed.