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

Fangrui Song i@maskray.me
Sat Jun 22 17:31:20 GMT 2024


On Sat, Jun 22, 2024 at 3:03 AM Xi Ruoyao <xry111@xry111.site> wrote:
>
> 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.
>
> 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>

LGTM.

DLL => DSO ?

> ---
>  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
> --
> 2.45.2
>


More information about the Binutils mailing list