Bug 24302 - When DF_BIND_NOW the dt_tlsdesc_got should not be used
Summary: When DF_BIND_NOW the dt_tlsdesc_got should not be used
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.31
: P2 critical
Target Milestone: 2.32
Assignee: Tamar Christina
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-03-05 03:50 UTC by Tao Wang
Modified: 2019-04-18 16:22 UTC (History)
1 user (show)

See Also:
Host:
Target: aarch64-*-*
Build:
Last reconfirmed: 2019-03-29 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tao Wang 2019-03-05 03:50:52 UTC
Hi All,
  I produced a problem, and after debugging it seems that in elfNN_aarch64_finish_dynamic_sections the value of htab->dt_tlsdesc_got should be checked. If the htab->dt_tlsdesc_got is -1, then htab->root.sgot->contents should not add it, otherwise this code will overwrite the contents of the previous byte. The maybe-error code is as follows:
      if (htab->tlsdesc_plt)
	{
	  bfd_put_NN (output_bfd, (bfd_vma) 0,
		      htab->root.sgot->contents + htab->dt_tlsdesc_got);

	  memcpy (htab->root.splt->contents + htab->tlsdesc_plt,
		  elfNN_aarch64_tlsdesc_small_plt_entry,
		  sizeof (elfNN_aarch64_tlsdesc_small_plt_entry));

  This is aarch64 backend, and the only assignment of dt_tlsdesc_got is limited by DF_BIND_NOW. when linking with "-z now", this code won't be executed
      /* If we're not using lazy TLS relocations, don't generate the
	 GOT entry required.  */
      if (!(info->flags & DF_BIND_NOW))
	{
	  htab->dt_tlsdesc_got = htab->root.sgot->size;
	  htab->root.sgot->size += GOT_ENTRY_SIZE;
	}
So anyone can explain this? Is htab->dt_tlsdesc_got needed to check validaty before using in elfNN_aarch64_finish_dynamic_sections?

Because it needs many object file to reproduce this problem, I can't upload a testcase. I'll be very grateful if someone can explain the code.

Thanks
Comment 1 Tao Wang 2019-03-12 01:01:39 UTC
Can anyone have a look at this problem ?
Comment 2 Tamar Christina 2019-03-25 15:24:22 UTC
Hi Tao,

Thanks for the report, I'll take a look!
Comment 3 Tamar Christina 2019-03-29 15:53:59 UTC
Confirmed.
Comment 4 Sourceware Commits 2019-04-11 10:38:38 UTC
The master branch has been updated by Tamar Christina <tnfchris@sourceware.org>:

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

commit ce12121b63145322b4961bbb2b94b939cb916ba7
Author: Tamar Christina <tamar.christina@arm.com>
Date:   Thu Apr 11 11:27:28 2019 +0100

    AArch64: When DF_BIND_NOW don't use TLSDESC GOT value.
    
    When using DF_BIND_NOW on AArch64 we don't reserve the GOT slot for a TLSDESC,
    but we still emitted DT_TLSDESC_GOT and DT_TLSDESC_PLT.  This caused random
    memory corruption as the "special" value of (bfd_vma)-1 would be set for
    dt_tlsdesc_got.
    
    Since we don't have a value of dt_tlsdesc_got I also don't emit DT_TLSDESC_PLT
    now becuase it would point to an incomplete PLT. To be able to write the PLT
    entry DT_TLSDESC_GOT is needed and since we don't have one we can't write the
    PLT entry either.
    
    It is my understanding that GLIBC doesn't need these two entries when not lazy
    loading.  Conversely AArch32 does not reserve neither the GOT not the PLT slot
    when doing DF_BIND_NOW.
    
    AArch32 does not need these checks because these values are initialized to 0
    and so the if (...) checks don't pass, but on AArch64 these are initialized
    to (bfd_vma)-1 and thus we need some extra checks.
    
    bfd/ChangeLog:
    
    	PR ld/24302
    	* elfnn-aarch64.c (elfNN_aarch64_size_dynamic_sections): Don't emit
    	DT_TLSDESC_GOT and DT_TLSDESC_PLT when DF_BIND_NOW.
    	(elfNN_aarch64_finish_dynamic_sections): Don't write PLT if DF_BIND_NOW.
    
    ld/ChangeLog:
    
    	PR ld/24302
    	* testsuite/ld-aarch64/aarch64-elf.exp: Add new test.
    	* testsuite/ld-aarch64/tls-relax-gdesc-le-now.d: New test.
Comment 5 Tamar Christina 2019-04-11 10:40:20 UTC
Waiting a few days to backport to the stable 2.32 branch.
Comment 6 Tao Wang 2019-04-11 11:26:11 UTC
(In reply to Tamar Christina from comment #5)
> Waiting a few days to backport to the stable 2.32 branch.

Thanks Tamar.
Comment 7 Sourceware Commits 2019-04-18 16:20:08 UTC
The binutils-2_32-branch branch has been updated by Tamar Christina <tnfchris@sourceware.org>:

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

commit eb23038d19295a783144ec266736d486e5671d96
Author: Tamar Christina <tamar.christina@arm.com>
Date:   Thu Apr 11 11:27:28 2019 +0100

    AArch64: When DF_BIND_NOW don't use TLSDESC GOT value.
    
    When using DF_BIND_NOW on AArch64 we don't reserve the GOT slot for a TLSDESC,
    but we still emitted DT_TLSDESC_GOT and DT_TLSDESC_PLT.  This caused random
    memory corruption as the "special" value of (bfd_vma)-1 would be set for
    dt_tlsdesc_got.
    
    Since we don't have a value of dt_tlsdesc_got I also don't emit DT_TLSDESC_PLT
    now becuase it would point to an incomplete PLT. To be able to write the PLT
    entry DT_TLSDESC_GOT is needed and since we don't have one we can't write the
    PLT entry either.
    
    It is my understanding that GLIBC doesn't need these two entries when not lazy
    loading.  Conversely AArch32 does not reserve neither the GOT not the PLT slot
    when doing DF_BIND_NOW.
    
    AArch32 does not need these checks because these values are initialized to 0
    and so the if (...) checks don't pass, but on AArch64 these are initialized
    to (bfd_vma)-1 and thus we need some extra checks.
    
    bfd/ChangeLog:
    
    	PR ld/24302
    	* elfnn-aarch64.c (elfNN_aarch64_size_dynamic_sections): Don't emit
    	DT_TLSDESC_GOT and DT_TLSDESC_PLT when DF_BIND_NOW.
    	(elfNN_aarch64_finish_dynamic_sections): Don't write PLT if DF_BIND_NOW.
    
    ld/ChangeLog:
    
    	PR ld/24302
    	* testsuite/ld-aarch64/aarch64-elf.exp: Add new test.
    	* testsuite/ld-aarch64/tls-relax-gdesc-le-now.d: New test.
    
    (cherry picked from commit ce12121b63145322b4961bbb2b94b939cb916ba7)
Comment 8 Tamar Christina 2019-04-18 16:22:17 UTC
Fixed in master and backported to 2.32. Thanks for the report!