From patchwork Fri Apr 28 09:51:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hou Wenlong X-Patchwork-Id: 88558 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp817430vqo; Fri, 28 Apr 2023 03:04:06 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ4BctokDopixUkLRmRDVjl39IwA+PxIzkbvQe/scA5cVm4lFLykz58VKgThbR0Lwtorkscw X-Received: by 2002:a05:6a00:1799:b0:627:f1f1:a97d with SMTP id s25-20020a056a00179900b00627f1f1a97dmr7389138pfg.24.1682676246589; Fri, 28 Apr 2023 03:04:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1682676246; cv=none; d=google.com; s=arc-20160816; b=hjalP95KthnmRc0D4+Kc54fA3tTtgY627mq/HAOp/YsfV5WAqiab09Ui1ukDrK1DN7 WwzfH1XnuhHPHyTuGJ7md+4Be4hp4qph6S8+1d++it58gcqeaHQieduSlKRSVAGEvOvX GY69yyaK0QAvNGBOs13G3jBnJ0hZlgqqkRo5T7HtR4aPwfOoqF9t/1/Hjk/6T5gdPN5Y 4kHdJBv+9U+4lg0dL8DLix3UzZaYkVKLVLv8+EoVCzQAMzqepADvuJ5AGAONqoxksIQW 59NrXJ/swukgzSlov/EAUp9o6N5cinbAMw3bvmoGwnPARhTHXUGPJwD2U7+Ss3t0mJmz kIdg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=wB4eCOUuF/FivmrzDq5iZt/tTBt6ePkFydUtKZvVHqU=; b=TudQLXDio1Us4P3GICpB12Gh4pI2J5Ef2nXuJOgmVOv1ReWcUKIRfKqrhVm7bzKFXS CrW9qtIY8MUhYq2GwIceFUHtU9eQLLDJvpVaUtikyCJT+AAqmryOqFvha+SF7jEw635r OdAE6EAWeHIQjRVvX7oYHJ8aylvSuXccdPnJ/VZK3nF359gvCKzaqTd59ZrPeNlwvck9 NRYAnTLGAL9OhVPklwlfnnOFC1oq2dWK5V8f5+7Vhuaw48JaNHxllFlg7dDIXnMoHdIa FNMUqOBI9MWFYJI48lczeJdLTPIKZfWmqnUKLYbSvl6SOwd4Gp3Uq8oJa2mmE3n7CV1T lUKQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=antgroup.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e125-20020a636983000000b00524f00fee68si16861896pgc.372.2023.04.28.03.03.53; Fri, 28 Apr 2023 03:04:06 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=antgroup.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346039AbjD1J5i (ORCPT + 99 others); Fri, 28 Apr 2023 05:57:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36920 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346033AbjD1J5U (ORCPT ); Fri, 28 Apr 2023 05:57:20 -0400 Received: from out187-21.us.a.mail.aliyun.com (out187-21.us.a.mail.aliyun.com [47.90.187.21]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2F7ED5BA0 for ; Fri, 28 Apr 2023 02:56:19 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R151e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018047187;MF=houwenlong.hwl@antgroup.com;NM=1;PH=DS;RN=13;SR=0;TI=SMTPD_---.STFoGX6_1682675596; Received: from localhost(mailfrom:houwenlong.hwl@antgroup.com fp:SMTPD_---.STFoGX6_1682675596) by smtp.aliyun-inc.com; Fri, 28 Apr 2023 17:53:17 +0800 From: "Hou Wenlong" To: linux-kernel@vger.kernel.org Cc: "Thomas Garnier" , "Lai Jiangshan" , "Kees Cook" , "Hou Wenlong" , "Thomas Gleixner" , "Ingo Molnar" , "Borislav Petkov" , "Dave Hansen" , , "H. Peter Anvin" , "Sami Tolvanen" , " =?utf-8?q?Peter_Zijlstra_=28Intel=29?= " Subject: [PATCH RFC 27/43] x86/relocs: Handle PIE relocations Date: Fri, 28 Apr 2023 17:51:07 +0800 Message-Id: X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE,UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1764413928219132534?= X-GMAIL-MSGID: =?utf-8?q?1764413928219132534?= From: Thomas Garnier From: Thomas Garnier Change the relocation tool to correctly handle relocations generated by -fPIE option: - Add relocation for each entry of the .got section given the linker does not generate R_X86_64_GLOB_DAT on a simple link. - Ignore R_X86_64_GOTPCREL. Signed-off-by: Thomas Garnier Signed-off-by: Hou Wenlong Cc: Lai Jiangshan Cc: Kees Cook --- arch/x86/tools/relocs.c | 96 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c index 038e9c12fad3..97ac96195232 100644 --- a/arch/x86/tools/relocs.c +++ b/arch/x86/tools/relocs.c @@ -42,6 +42,7 @@ struct section { Elf32_Word *xsymtab; Elf_Rel *reltab; char *strtab; + Elf_Addr *got; }; static struct section *secs; @@ -308,6 +309,36 @@ static Elf_Sym *sym_lookup(const char *symname) return 0; } +static Elf_Sym *sym_lookup_addr(Elf_Addr addr, const char **name) +{ + int i; + + for (i = 0; i < ehdr.e_shnum; i++) { + struct section *sec = &secs[i]; + long nsyms; + Elf_Sym *symtab; + Elf_Sym *sym; + + if (sec->shdr.sh_type != SHT_SYMTAB) + continue; + + nsyms = sec->shdr.sh_size/sizeof(Elf_Sym); + symtab = sec->symtab; + + for (sym = symtab; --nsyms >= 0; sym++) { + if (sym->st_value == addr) { + if (name) { + *name = sym_name(sec->link->strtab, + sym); + } + return sym; + } + } + } + return 0; +} + + #if BYTE_ORDER == LITTLE_ENDIAN #define le16_to_cpu(val) (val) #define le32_to_cpu(val) (val) @@ -588,6 +619,35 @@ static void read_relocs(FILE *fp) } } +static void read_got(FILE *fp) +{ + int i; + + for (i = 0; i < ehdr.e_shnum; i++) { + struct section *sec = &secs[i]; + + sec->got = NULL; + if (sec->shdr.sh_type != SHT_PROGBITS || + strcmp(sec_name(i), ".got")) { + continue; + } + sec->got = malloc(sec->shdr.sh_size); + if (!sec->got) { + die("malloc of %" FMT " bytes for got failed\n", + sec->shdr.sh_size); + } + if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) { + die("Seek to %" FMT " failed: %s\n", + sec->shdr.sh_offset, strerror(errno)); + } + if (fread(sec->got, 1, sec->shdr.sh_size, fp) + != sec->shdr.sh_size) { + die("Cannot read got: %s\n", + strerror(errno)); + } + } +} + static void print_absolute_symbols(void) { @@ -718,6 +778,32 @@ static void add_reloc(struct relocs *r, uint32_t offset) r->offset[r->count++] = offset; } +/* + * The linker does not generate relocations for the GOT for the kernel. + * If a GOT is found, simulate the relocations that should have been included. + */ +static void walk_got_table(int (*process)(struct section *sec, Elf_Rel *rel, + Elf_Sym *sym, const char *symname), + struct section *sec) +{ + int i; + Elf_Addr entry; + Elf_Sym *sym; + const char *symname; + Elf_Rel rel; + + for (i = 0; i < sec->shdr.sh_size/sizeof(Elf_Addr); i++) { + entry = sec->got[i]; + sym = sym_lookup_addr(entry, &symname); + if (!sym) + die("Could not found got symbol for entry %d\n", i); + rel.r_offset = sec->shdr.sh_addr + i * sizeof(Elf_Addr); + rel.r_info = ELF_BITS == 64 ? R_X86_64_GLOB_DAT + : R_386_GLOB_DAT; + process(sec, &rel, sym, symname); + } +} + static void walk_relocs(int (*process)(struct section *sec, Elf_Rel *rel, Elf_Sym *sym, const char *symname)) { @@ -731,6 +817,8 @@ static void walk_relocs(int (*process)(struct section *sec, Elf_Rel *rel, struct section *sec = &secs[i]; if (sec->shdr.sh_type != SHT_REL_TYPE) { + if (sec->got) + walk_got_table(process, sec); continue; } sec_symtab = sec->link; @@ -842,6 +930,7 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym, offset += per_cpu_load_addr; switch (r_type) { + case R_X86_64_GOTPCREL: case R_X86_64_NONE: /* NONE can be ignored. */ break; @@ -905,7 +994,7 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym, * the relocations are processed. * Make sure that the offset will fit. */ - if ((int32_t)offset != (int64_t)offset) + if (r_type != R_X86_64_64 && (int32_t)offset != (int64_t)offset) die("Relocation offset doesn't fit in 32 bits\n"); if (r_type == R_X86_64_64) @@ -914,6 +1003,10 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym, add_reloc(&relocs32, offset); break; + case R_X86_64_GLOB_DAT: + add_reloc(&relocs64, offset); + break; + default: die("Unsupported relocation type: %s (%d)\n", rel_type(r_type), r_type); @@ -1188,6 +1281,7 @@ void process(FILE *fp, int use_real_mode, int as_text, read_strtabs(fp); read_symtabs(fp); read_relocs(fp); + read_got(fp); if (ELF_BITS == 64) percpu_init(); if (show_absolute_syms) {