lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <99733532831377ab6585d43ee40bf314a2d4c5a3.camel@xry111.site>
Date:   Thu, 28 Jul 2022 00:28:39 +0800
From:   Xi Ruoyao <xry111@...111.site>
To:     loongarch@...ts.linux.dev
Cc:     linux-kernel@...r.kernel.org, WANG Xuerui <kernel@...0n.name>,
        Huacai Chen <chenhuacai@...nel.org>
Subject: [PATCH 3/5] LoongArch: Support relocation against
 _GLOBAL_OFFSET_TABLE_

With the stack-based relocations, the assembler emits three relocations
to push the PC-relative offset of a GOT entry:

    R_LARCH_SOP_PUSH_PCREL _GLOBAL_OFFSET_TABLE_
    R_LARCH_SOP_PUSH_GPREL foo
    R_LARCH_SOP_ADD

"_GLOBAL_OFFSET_TABLE_" does not really exist in the symtab and the BFD
linker handles it with special hack.  Implement a similar hack for
kernel so we will be able to really use R_LARCH_SOP_PUSH_GPREL
relocation.

Signed-off-by: Xi Ruoyao <xry111@...111.site>
---
 arch/loongarch/kernel/module-sections.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/loongarch/kernel/module-sections.c b/arch/loongarch/kernel/module-sections.c
index 509c0b86b1e9..73976addbf60 100644
--- a/arch/loongarch/kernel/module-sections.c
+++ b/arch/loongarch/kernel/module-sections.c
@@ -89,6 +89,9 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
 			      char *secstrings, struct module *mod)
 {
 	unsigned int i, num_plts = 0, num_gots = 0;
+	Elf_Shdr *symtab = NULL;
+	Elf_Sym *symbols;
+	char *strings;
 
 	/*
 	 * Find the empty .plt sections.
@@ -100,6 +103,8 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
 			mod->arch.plt_idx.shdr = sechdrs + i;
 		else if (!strcmp(secstrings + sechdrs[i].sh_name, ".got"))
 			mod->arch.got.shdr = sechdrs + i;
+		else if (sechdrs[i].sh_type == SHT_SYMTAB)
+			symtab = sechdrs + i;
 	}
 
 	if (!mod->arch.plt.shdr) {
@@ -115,6 +120,22 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
 		return -ENOEXEC;
 	}
 
+	if (!symtab) {
+		pr_err("%s: module symbol table missing\n", mod->name);
+		return -ENOEXEC;
+	}
+
+	symbols = (void *) ehdr + symtab->sh_offset;
+	strings = (void *) ehdr + sechdrs[symtab->sh_link].sh_offset;
+
+	for (i = 0; i < symtab->sh_size / sizeof(Elf_Sym); i++)
+		if (symbols[i].st_shndx == SHN_UNDEF &&
+		    strcmp(strings + symbols[i].st_name,
+			   "_GLOBAL_OFFSET_TABLE_") == 0) {
+			symbols[i].st_shndx = mod->arch.got.shdr - sechdrs;
+			symbols[i].st_value = 0;
+		}
+
 	/* Calculate the maxinum number of entries */
 	for (i = 0; i < ehdr->e_shnum; i++) {
 		int num_rela = sechdrs[i].sh_size / sizeof(Elf_Rela);
-- 
2.37.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ