[PATCH 1/5] LoongArch: Reject R_LARCH_32 from becoming a runtime reloc in ELFCLASS64

mengqinggang mengqinggang@loongson.cn
Mon Jun 24 08:45:48 GMT 2024


在 2024/6/22 下午6:03, Xi Ruoyao 写道:
> We were converting R_LARCH_32 to R_LARCH_RELATIVE for ELFCLASS64:
>
>      $ cat t.s
>      .data
>      x:
>          .4byte x
>      $ as/as-new t.s -o t.o
>      $ ld/ld-new -shared t.s
>      $ objdump -R
>      a.out:     file format elf64-loongarch
>
>      DYNAMIC RELOCATION RECORDS
>      OFFSET           TYPE              VALUE
>      00000000000001a8 R_LARCH_RELATIVE  *ABS*+0x00000000000001a8
>
> But this is just wrong: at runtime the dynamic linker will run
> *(uintptr *)&x += load_address, causing an OOB write.


OOB write means R_LARCH_RELATIVE writes 8 bytes to 4 bytes?


>
> It does not make too much sense to support R_LARCH_32 in ELFCLASS64 or
> R_LARCH_64 in ELFCLASS32 when creating a DLL or PIE.  And, if we keep it
> as-is in the linked object, it'll be rejected by Glibc dynamic linker
> anyway.  So we can just reject it like x86_64 and RISC-V.
>
> Signed-off-by: Xi Ruoyao <xry111@xry111.site>
> ---
>   bfd/elfnn-loongarch.c                         | 23 ++++++++++++++++++-
>   .../ld-loongarch-elf/ld-loongarch-elf.exp     |  1 +
>   .../ld-loongarch-elf/r_larch_32_elf64.d       |  4 ++++
>   .../ld-loongarch-elf/r_larch_32_elf64.s       |  3 +++
>   4 files changed, 30 insertions(+), 1 deletion(-)
>   create mode 100644 ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.d
>   create mode 100644 ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.s
>
> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
> index b1720760475..3a55ac93e20 100644
> --- a/bfd/elfnn-loongarch.c
> +++ b/bfd/elfnn-loongarch.c
> @@ -2861,7 +2861,28 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
>   	      /* No alloc space of func allocate_dynrelocs.  */
>   	      if (unresolved_reloc
>   		  && !(h && (h->is_weakalias || !h->dyn_relocs)))
> -		loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
> +		{
> +		  if (is_pic && r_type != R_LARCH_NN)
> +		    {
> +		      /* Not to use ELFCLASSNN in string literal or it'll
> +			 puzzle gettext.  */
> +
> +		      /* xgettext:c-format  */
> +		      char *msg = bfd_asprintf (
> +			_("reloc is unresolved and cannot be turned to "
> +			  "a runtime reloc in ELFCLASS%d"),
> +			NN);
> +
> +		      /* loongarch_reloc_is_fatal will output
> +			 "R_LARCH_32" or "R_LARCH_64" for us.  */
> +		      fatal = loongarch_reloc_is_fatal (
> +			info, input_bfd, input_section, rel, howto,
> +			bfd_reloc_notsupported, is_undefweak, name, msg);
> +		    }
> +		  else
> +		    loongarch_elf_append_rela (output_bfd, sreloc,
> +					       &outrel);
> +		}
>   	    }
>   
>   	  relocation += rel->r_addend;
> diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
> index d833a89246e..70625fa8dfe 100644
> --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
> +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
> @@ -139,6 +139,7 @@ if [istarget "loongarch64-*-*"] {
>       run_dump_test "reloc_le_with_shared"
>       run_dump_test "reloc_ler_with_shared"
>       run_dump_test "reloc_abs_with_shared"
> +    run_dump_test "r_larch_32_elf64"
>     }
>   
>     if [check_pie_support] {
> diff --git a/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.d b/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.d
> new file mode 100644
> index 00000000000..df61f3a36c5
> --- /dev/null
> +++ b/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.d
> @@ -0,0 +1,4 @@
> +#name: R_LARCH_32 in ELFCLASS64
> +#source: r_larch_32_elf64.s
> +#ld: -shared -melf64loongarch
> +#error: R_LARCH_32 against `x':\nreloc is unresolved and cannot be turned to a runtime reloc in ELFCLASS64
> diff --git a/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.s b/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.s
> new file mode 100644
> index 00000000000..6649f2bce01
> --- /dev/null
> +++ b/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.s
> @@ -0,0 +1,3 @@
> +.data
> +x:
> +	.4byte x



More information about the Binutils mailing list