public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* RFC: Can static executables contain relocations against symbols ?
@ 2023-03-29 14:39 Nick Clifton
  2023-03-29 15:47 ` Mark Wielaard
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Nick Clifton @ 2023-03-29 14:39 UTC (permalink / raw)
  To: binutils; +Cc: mjw, amulhern

Hi Guys,

  Can static executables contain relocations against symbols ?

  This question has come up in Fedora as part of the investigation into
  a problem linking some binaries compiled with the Rust compiler:

https://bugzilla.redhat.com/show_bug.cgi?id=2166149

  The issue appears to be that static-pie executables are being created
  with a .rela.got section that has an sh_link field set to point to the
  .symtab section.  This in turns means that running strip on the
  executables will not remove the .symtab section, which is then being
  flagged as an error by the build system.

  The problem is not happening for x86_64 binaries because they contain
  a .dynsym section, and the code in bfd/elf.c:assign_section_numbers
  will preferentially use that section if it exists.  (It is not clear
  to me *why* x86_64 static pie binaries contain a .dynsym section, but
  they do).

  It is possible for static executables to contain relocations - for
  ifuncs for example - but I think that they should always be absolute.
  So my question is: is it safe to set the sh_link field for relocation
  sections in static executables to 0 ?

  The attached patch is a suggestion for the change I am considering...

  Thoughts ?
  
Cheers
  Nick

diff --git a/bfd/elf.c b/bfd/elf.c
index 45e53640e8f..0b5c8c79fd6 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -3884,7 +3884,25 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
 		d->this_hdr.sh_link = elf_section_data (s)->this_idx;
 	    }
 	  if (d->this_hdr.sh_link == 0)
-	    d->this_hdr.sh_link = elf_onesymtab (abfd);
+	    {
+	      /* In general static executables should not need relocations.
+		 There are exceptions however, for ifuncs for example, but
+		 in these cases the relocations should not need any symbols.
+		 Hence it should be safe to leave the sh_link field as 0.
+		 Not setting sh_link allows the symbol table to be stripped
+		 from the executable, which is a desirable trait.
+
+		 FIXME: Should we scan the relocations first to make sure
+		 that there are no symbol references ?  */
+	      if (link_info != NULL
+		  && bfd_link_executable (link_info)
+		  && (abfd->flags & DYNAMIC) == 0)
+		;
+	      else
+		d->this_hdr.sh_link = elf_onesymtab (abfd);
+	    }
 
 	  s = elf_get_reloc_section (sec);
 	  if (s != NULL)


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: Can static executables contain relocations against symbols ?
  2023-03-29 14:39 RFC: Can static executables contain relocations against symbols ? Nick Clifton
@ 2023-03-29 15:47 ` Mark Wielaard
  2023-03-29 16:00 ` Michael Matz
  2023-03-30  1:22 ` Alan Modra
  2 siblings, 0 replies; 7+ messages in thread
From: Mark Wielaard @ 2023-03-29 15:47 UTC (permalink / raw)
  To: Nick Clifton, binutils; +Cc: amulhern

Hi Nick,

On Wed, 2023-03-29 at 15:39 +0100, Nick Clifton wrote:
>   Can static executables contain relocations against symbols ?

I see nothing in the standard that says they cannot, but also nothing
that says that if there are no relocations against symbols (which is
the case in the issue below) that a relocation section is required to
point to a symbol table.

>   This question has come up in Fedora as part of the investigation into
>   a problem linking some binaries compiled with the Rust compiler:
> 
> https://bugzilla.redhat.com/show_bug.cgi?id=2166149
> 
>   The issue appears to be that static-pie executables are being created
>   with a .rela.got section that has an sh_link field set to point to the
>   .symtab section.  This in turns means that running strip on the
>   executables will not remove the .symtab section, which is then being
>   flagged as an error by the build system.
> 
>   The problem is not happening for x86_64 binaries because they contain
>   a .dynsym section, and the code in bfd/elf.c:assign_section_numbers
>   will preferentially use that section if it exists.  (It is not clear
>   to me *why* x86_64 static pie binaries contain a .dynsym section, but
>   they do).

Note that the x86_64 .dynsym table actually is empty (contains a single
null symbol). I think it makes sense that if you refer from an
allocated relocation section to reference an allocated .dynsym section
(even if it is empty) instead of referencing an unallocated .symtab
section (because that won't be available at runtime).

>   It is possible for static executables to contain relocations - for
>   ifuncs for example - but I think that they should always be absolute.
>   So my question is: is it safe to set the sh_link field for relocation
>   sections in static executables to 0 ?

I think it is safe if you make sure there are no symbol references.
Otherwise it seems it must point to an allocated .dynsym section and
not an unallocated .symtab section.

Cheers,

Mark

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: Can static executables contain relocations against symbols ?
  2023-03-29 14:39 RFC: Can static executables contain relocations against symbols ? Nick Clifton
  2023-03-29 15:47 ` Mark Wielaard
@ 2023-03-29 16:00 ` Michael Matz
  2023-03-30  1:22 ` Alan Modra
  2 siblings, 0 replies; 7+ messages in thread
From: Michael Matz @ 2023-03-29 16:00 UTC (permalink / raw)
  To: Nick Clifton; +Cc: binutils, mjw, amulhern

Hello,

On Wed, 29 Mar 2023, Nick Clifton via Binutils wrote:

>   Can static executables contain relocations against symbols ?

Generally I agree with you that they should not.  Only symbol-less 
relocations make sense (not all of them will be absolute, though.  In PIEs 
they will be base-relative, still symbolless of course).  But for the sake 
of discussion let's assume we somehow want to allow symbol-based relocs 
nevertheless.  Then:

In final-linked ELF files symbol headers always have to be optional.  The 
place of relocations, if necessary, (and symbols) needs to be communicated 
in a different way anyway (on dynamic ELF files via the program headers 
and dynamic entries, on static files via some other side channel, like 
hardcoding the offset/addresses of the interesting pieces).

But: there is another observation that makes the Rust output invalid.  An 
allocated (SHF_ALLOC) section (here .got.rela) _must_ only refer to 
allocated sections via its sh_link field.  The .symtab section in the 
example at hand was not SHF_ALLOC.  So that's another bug.

Leaving a sh_link field of an SHT_RELA section to be zero seems a bit 
dubious.  Normally client code would be able to rely on sh_link containing 
an existing section index.  OTOH SHN_UNDEF (i.e. zero) _is_ somewhat of a 
section index, so leaving it as zero might just be fine.

So, even if the above problems would be fixed I think your patch still 
makes sense.  Perhaps add another check to only leave it zero if 
elf_onesymtab is not allocated itself.


Ciao,
Michael.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: Can static executables contain relocations against symbols ?
  2023-03-29 14:39 RFC: Can static executables contain relocations against symbols ? Nick Clifton
  2023-03-29 15:47 ` Mark Wielaard
  2023-03-29 16:00 ` Michael Matz
@ 2023-03-30  1:22 ` Alan Modra
  2023-03-30  4:54   ` Alan Modra
  2 siblings, 1 reply; 7+ messages in thread
From: Alan Modra @ 2023-03-30  1:22 UTC (permalink / raw)
  To: Nick Clifton; +Cc: binutils, mjw, amulhern

On Wed, Mar 29, 2023 at 03:39:46PM +0100, Nick Clifton via Binutils wrote:
>   The issue appears to be that static-pie executables are being created
>   with a .rela.got section that has an sh_link field set to point to the
>   .symtab section.

Nick, the patch you posted is for code with this comment:
	case SHT_REL:
	case SHT_RELA:
	  /* A reloc section which we are treating as a normal BFD
	     section.  sh_link is the section index of the symbol
	     table.  sh_info is the section index of the section to
	     which the relocation entries apply.  We assume that an
	     allocated reloc section uses the dynamic symbol table
	     if there is one.  Otherwise we guess the normal symbol
	     table.  FIXME: How can we be sure?  */

ie. we are way off into the weeds already.  However, I think the
comment is wrongly placed, because it looks to me like we handle the
usual SHT_REL/SHT_RELA sections here too.

So is the .rela.got (or .rela.plt) section one of the reloc sections
created in bfd_section_from_shdr elf.c:2382?  If we need to handle
this sort of reloc section better (and I doubt we do need to) then we
should do something about tracking the original sh_link and sh_info
fields when creating them,  Hmm, maybe they are still available, and
can be mapped to output sections?

Anyway, does the following fix the particular problem you are seeing?

diff --git a/bfd/elf.c b/bfd/elf.c
index 45e53640e8f..027d0143735 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -3870,21 +3870,23 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
 	{
 	case SHT_REL:
 	case SHT_RELA:
-	  /* A reloc section which we are treating as a normal BFD
-	     section.  sh_link is the section index of the symbol
-	     table.  sh_info is the section index of the section to
-	     which the relocation entries apply.  We assume that an
-	     allocated reloc section uses the dynamic symbol table
-	     if there is one.  Otherwise we guess the normal symbol
-	     table.  FIXME: How can we be sure?  */
-	  if (d->this_hdr.sh_link == 0 && (sec->flags & SEC_ALLOC) != 0)
-	    {
-	      s = bfd_get_section_by_name (abfd, ".dynsym");
-	      if (s != NULL)
-		d->this_hdr.sh_link = elf_section_data (s)->this_idx;
-	    }
+	  /* sh_link is the section index of the symbol table.
+	     sh_info is the section index of the section to which the
+	     relocation entries apply.  */
 	  if (d->this_hdr.sh_link == 0)
-	    d->this_hdr.sh_link = elf_onesymtab (abfd);
+	    {
+	      /* FIXME maybe: If this is a reloc section which we are
+		 treating as a normal section then we likely should
+		 not be assuming its sh_link is .dynsym or .symtab.  */
+	      if ((sec->flags & SEC_ALLOC) != 0)
+		{
+		  s = bfd_get_section_by_name (abfd, ".dynsym");
+		  if (s != NULL)
+		    d->this_hdr.sh_link = elf_section_data (s)->this_idx;
+		}
+	      else
+		d->this_hdr.sh_link = elf_onesymtab (abfd);
+	    }
 
 	  s = elf_get_reloc_section (sec);
 	  if (s != NULL)

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: Can static executables contain relocations against symbols ?
  2023-03-30  1:22 ` Alan Modra
@ 2023-03-30  4:54   ` Alan Modra
  2023-03-30  8:57     ` Nick Clifton
  0 siblings, 1 reply; 7+ messages in thread
From: Alan Modra @ 2023-03-30  4:54 UTC (permalink / raw)
  To: Nick Clifton; +Cc: binutils, mjw, amulhern

On Thu, Mar 30, 2023 at 11:52:01AM +1030, Alan Modra wrote:
> Anyway, does the following fix the particular problem you are seeing?

I'm going to commit the patch even if it doesn't fix your problem
since that 1995 comment from commit ede4eed48386 needs fixing, and
it's wrong to use a non-alloc symtab with an alloc reloc section as
others have commented.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: Can static executables contain relocations against symbols ?
  2023-03-30  4:54   ` Alan Modra
@ 2023-03-30  8:57     ` Nick Clifton
  2023-03-30  9:12       ` Alan Modra
  0 siblings, 1 reply; 7+ messages in thread
From: Nick Clifton @ 2023-03-30  8:57 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils, mjw, amulhern

Hi Alan,

>> Anyway, does the following fix the particular problem you are seeing?

I am not sure - I will have to investigate.  Reproducing the original
problem is difficult because it involves using the Rust compiler on
a non-x86_64 platform, so it may take me a while.

> I'm going to commit the patch even if it doesn't fix your problem
> since that 1995 comment from commit ede4eed48386 needs fixing, and
> it's wrong to use a non-alloc symtab with an alloc reloc section as
> others have commented.

That is a good point.  Thanks for creating a better patch.

Cheers
   Nick



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: RFC: Can static executables contain relocations against symbols ?
  2023-03-30  8:57     ` Nick Clifton
@ 2023-03-30  9:12       ` Alan Modra
  0 siblings, 0 replies; 7+ messages in thread
From: Alan Modra @ 2023-03-30  9:12 UTC (permalink / raw)
  To: Nick Clifton; +Cc: binutils, mjw, amulhern

Hi Nick,
On Thu, Mar 30, 2023 at 09:57:42AM +0100, Nick Clifton wrote:
> That is a good point.  Thanks for creating a better patch.

Eh, well, it was likeley bad code of mine from commit b6d1f70cc7e9
that caused the problem in the first place.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2023-03-30  9:12 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-29 14:39 RFC: Can static executables contain relocations against symbols ? Nick Clifton
2023-03-29 15:47 ` Mark Wielaard
2023-03-29 16:00 ` Michael Matz
2023-03-30  1:22 ` Alan Modra
2023-03-30  4:54   ` Alan Modra
2023-03-30  8:57     ` Nick Clifton
2023-03-30  9:12       ` Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).