[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