From patchwork Fri Apr 28 09:51:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hou Wenlong X-Patchwork-Id: 88553 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp816467vqo; Fri, 28 Apr 2023 03:02:30 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7x5PWRbwRb0G3n3iieoMvN77vTJlL4v3in8NLh6ICiTvku5uK95UAMRbvTv0hbzkbDS1Qj X-Received: by 2002:a05:6a00:1749:b0:63d:287f:fdf5 with SMTP id j9-20020a056a00174900b0063d287ffdf5mr6772558pfc.27.1682676149804; Fri, 28 Apr 2023 03:02:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1682676149; cv=none; d=google.com; s=arc-20160816; b=jy0+qbENLW5cOEjgaa8HgKX2JfUZSxVZeBdZhAoFaxvIp0WYDKopvbgPYEy391XSxO OwfOKcTtQVKf3LNyBYgZJu/z9Qg1uzVNvvsGysGxJlvdgyEQrvcut4AIoGETJ1tdn3MS EvlLAxKY0ZgsOUu/+2wKk3FF0Z39eG02nUTUYAO0JgmKQWTHojJc6btcABOlt+Hy47h3 1Ou4WLgLxfqQbUCkrnDJfZm8xWmnDgAsVu84ITVFGiXfDtu+3PMwdP39143SboDoCbZJ tDC0IbdEEEw9rOMolC0KxkyTz4OJPa2glLNpfkozqd2e7LKrLTdaTAQdAysE2ol/Ihb3 8QGA== 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=JuYTGEVdqhGZqgILy32ZsaJ8AH9R5mp/gGPOasnJusk=; b=V42ktFSDZVd7lL/0f2PwWyv+d1Kx+WNbo+UhvcPfJ5Em8dPqE1nnRZe+pQ1Zpn3Mng 02TPhpdjoPvWrEatdROJgINEObjxKgeErqoXnDh6t2gJWpL+xiWhQ9eRmhsRD5IIrYDR Dp8Pz3ySGnAcvXQpzwhmIOsc/p+DFVVwAdMuxR1m3nvVT74m9siD5f8NC19aRK8X7v6a UzHlEGQmKwUvjJb6QLy3PPBaQNZ2S0pj6Fk8eT+P5om2RvKk6mzJqupKnmu1h6hBvDL0 0yxRL5/lU4MnSycOkOoO012tDkAxg7AqBaT9z0/rF1GmWLH1l+iPOgXM+NeLiGs/yUYY Zrzg== 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 78-20020a630151000000b005287f5fbf5esi7551564pgb.254.2023.04.28.03.02.17; Fri, 28 Apr 2023 03:02:29 -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 S1345869AbjD1J4A (ORCPT + 99 others); Fri, 28 Apr 2023 05:56:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36560 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345892AbjD1JzS (ORCPT ); Fri, 28 Apr 2023 05:55:18 -0400 Received: from out187-19.us.a.mail.aliyun.com (out187-19.us.a.mail.aliyun.com [47.90.187.19]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E2F1759FD for ; Fri, 28 Apr 2023 02:54:59 -0700 (PDT) X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R821e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018047190;MF=houwenlong.hwl@antgroup.com;NM=1;PH=DS;RN=15;SR=0;TI=SMTPD_---.STFoGfH_1682675620; Received: from localhost(mailfrom:houwenlong.hwl@antgroup.com fp:SMTPD_---.STFoGfH_1682675620) by smtp.aliyun-inc.com; Fri, 28 Apr 2023 17:53:41 +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" , "Josh Poimboeuf" , "Peter Zijlstra" , "Christophe Leroy" , "Sathvika Vasireddy" Subject: [PATCH RFC 34/43] objtool: Adapt indirect call of __fentry__() for PIE support Date: Fri, 28 Apr 2023 17:51:14 +0800 Message-Id: <804a7d5a4ef939b767ae540ebbb24a811d99e100.1682673543.git.houwenlong.hwl@antgroup.com> 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?1764413826536916551?= X-GMAIL-MSGID: =?utf-8?q?1764413826536916551?= When using PIE with function tracing, the compiler generates a call through the GOT (call *__fentry__@GOTPCREL). This instruction is an indirect call (INSN_CALL_DYNAMIC) and wouldn't be collected by add_call_destinations(). So collect those indirect calls of __fentry__() individually for PIE support. And replace the 6th byte of the GOT call by a 1-byte nop so ftrace can handle the previous 5-bytes as before. When RETPOLINE is enabled, __fentry__() is still an indirect call, which generates warnings in objtool. For simplicity, select DYNAMIC_FTRACE to patch it as NOPs. And regard it as INSN_CALL to omit warnings for jump table and retpoline checks in ojbtool. Signed-off-by: Hou Wenlong Cc: Thomas Garnier Cc: Lai Jiangshan Cc: Kees Cook --- arch/x86/Kconfig | 1 + tools/objtool/arch/x86/decode.c | 10 +++++++-- tools/objtool/check.c | 39 +++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index b753a54e5ea7..5ac5f335855e 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2225,6 +2225,7 @@ config X86_PIE def_bool n depends on X86_64 select OBJTOOL if HAVE_OBJTOOL + select DYNAMIC_FTRACE if FUNCTION_TRACER && RETPOLINE config RANDOMIZE_BASE bool "Randomize the address of the kernel image (KASLR)" diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c index 9ef024fd648c..cd9a81002efe 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -747,15 +747,21 @@ void arch_initial_func_cfi_state(struct cfi_init_state *state) const char *arch_nop_insn(int len) { - static const char nops[5][5] = { + static const char nops[6][6] = { { BYTES_NOP1 }, { BYTES_NOP2 }, { BYTES_NOP3 }, { BYTES_NOP4 }, { BYTES_NOP5 }, + /* + * For PIE kernel, use a 5-byte nop + * and 1-byte nop to keep the frace + * hooking algorithm working correct. + */ + { BYTES_NOP5, BYTES_NOP1 }, }; - if (len < 1 || len > 5) { + if (len < 1 || len > 6) { WARN("invalid NOP size: %d\n", len); return NULL; } diff --git a/tools/objtool/check.c b/tools/objtool/check.c index d67b80251eec..2456ab931fe5 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1785,6 +1785,38 @@ static int add_call_destinations(struct objtool_file *file) return 0; } +static int add_indirect_mcount_calls(struct objtool_file *file) +{ + struct instruction *insn; + struct reloc *reloc; + + for_each_insn(file, insn) { + if (insn->type != INSN_CALL_DYNAMIC) + continue; + + reloc = insn_reloc(file, insn); + if (!reloc) + continue; + if (!reloc->sym->fentry) + continue; + + /* + * __fentry__() is an indirect call even in RETPOLINE builiding + * when X86_PIE is enabled, so DYNAMIC_FTRACE is selected. Then + * all indirect calls of __fentry__() would be patched as NOP + * later, so regard it as retpoline safe as a hack here. Also + * regard it as a direct call, otherwise, it would be treat as + * a jump to jump table in insn_jump_table(), because + * _jump_table and _call_dest share the same memory. + */ + insn->type = INSN_CALL; + insn->retpoline_safe = true; + add_call_dest(file, insn, reloc->sym, false); + } + + return 0; +} + /* * The .alternatives section requires some extra special care over and above * other special sections because alternatives are patched in place. @@ -2668,6 +2700,13 @@ static int decode_sections(struct objtool_file *file) if (ret) return ret; + /* + * For X86 PIE kernel, __fentry__ call is an indirect call instead + * of direct call. + */ + if (opts.pie) + add_indirect_mcount_calls(file); + /* * Must be after add_call_destinations() such that it can override * dead_end_function() marks.