Message ID | 168899127520.80889.15418363018799407058.stgit@devnote2 |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:9f45:0:b0:3ea:f831:8777 with SMTP id v5csp4993336vqx; Mon, 10 Jul 2023 05:38:13 -0700 (PDT) X-Google-Smtp-Source: APBJJlF1WHd3DgvbjAP2QaFiMiMrrEUzgN0jDoANuZas+34S9B7gOacFu/q8wd5+TKz7KSC930Tp X-Received: by 2002:aa7:d91a:0:b0:51b:fbf3:d9a7 with SMTP id a26-20020aa7d91a000000b0051bfbf3d9a7mr11995264edr.39.1688992693706; Mon, 10 Jul 2023 05:38:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1688992693; cv=none; d=google.com; s=arc-20160816; b=iXC/a4S9oDjC3ax19/Mi5QAWCCSlgqYrI6P0pfUJUWBl4P/Qty2wkklne9rjTzzdxj aepqf4mCqLWbqNImyxHFJVjJJxoOQTldtD0TqcN4LJKTYjSz6tP7nm77RroG1NzptfMf v1V7Q7lRaLbVZ0I76PUhfvCkH913OjsJmYV0wKX2jCnnPerdrNaamyzb7QMnZD2/2B6f peZ5OSfkZXcECB55m24YOg56vWQWWvi19SpcWkj9q+uRBPG7PbQP/tbegGaoX3QnO2aT abmPX7wpr5FxWqlDqr4rBEV4vBeLgkD5YeDaITEAMbcIrsQSGm739rSF0a50fKChGDZy Pb7w== 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 :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=EpmgswIp+I0TLIhYt/2A6X9ydnnDN3n2TS2BkLyOpL8=; fh=B4q89xUy9DRjDdZZ7pfgA4xc0K5nMMNyHs2WNlwRQlk=; b=evK4ZlyacMCtvM59IcebQ5kvxS1MfMEH9UVUBsPTWEDCb/+6z/OtpBTRGKd5HBy0tB hgXwrmz6JZ1ia0+mkec3QkzzNyOtU3/AcNgpfpajVEU1N6Bfzkv5dMztDdNlOGUZV+z5 e3SP84EdB65qzDbahYHbLsMTSz+a6U13ksSDpVi5tQg2XnJnyx5vatwvPG7lIHL/rMtz J45HT2ON41npllAoPtX4Wl/TpqMt5PRCXq5YPRR1GHGBUTYqtA0HQroOW7mrKQpzPi8H tADVjTC/DEMcEL09TGNVz87pr63ndw9CBxnULkbKFUPT7fZb4vPp1/+z/b3ViOLAXQDz YxyQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=DuJ8f0e7; 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=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id q20-20020aa7da94000000b0051e226c4e6dsi10323655eds.278.2023.07.10.05.37.50; Mon, 10 Jul 2023 05:38:13 -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; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=DuJ8f0e7; 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=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231253AbjGJMOv (ORCPT <rfc822;ybw1215001957@gmail.com> + 99 others); Mon, 10 Jul 2023 08:14:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56536 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229759AbjGJMOq (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Mon, 10 Jul 2023 08:14:46 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 41775180; Mon, 10 Jul 2023 05:14:41 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 5D4BE60FD9; Mon, 10 Jul 2023 12:14:41 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id EE57AC433C9; Mon, 10 Jul 2023 12:14:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1688991280; bh=keXlJlAzhceOANDhcIRA1uDchUR8isMCDIVgVQwTE4A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DuJ8f0e72x8Q5m1yjEwl9Gx7RYAGn2V9Cy601y7bD2ecK4X4cHGOOCN0Kkzlnm/B3 /2Lmy9WhuBpa1bQKtGkK0dXCieP76n0BgarlhMvBqdMNAkvzz9J9zgm+ibjg0+Ijfj TqpJCkszJkzFxo61d7eKrA0eZwQ4vD9UJa01YO1hxM3kR8Eu3XYFuSULFdPGsDReS5 OGQR0/iMwLY42VlDMqFVIjNHPEr2o82sOyYLwkPmOFUpLH4S40fMyzcRN3tE/59W96 gfCtOUtvkpx4KaOLbaXFpx49s4zylVPvUdchhPIbP86VwaJKXQf7vyunHfkhtokiQG OfTRE9rzzx++A== From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org> To: Peter Zijlstra <peterz@infradead.org> Cc: Petr Pavlu <petr.pavlu@suse.com>, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com, samitolvanen@google.com, x86@kernel.org, linux-trace-kernel@vger.kernel.org, linux-kernel@vger.kernel.org, Masami Hiramatsu <mhiramat@kernel.org> Subject: [RFC PATCH 2/2] x86/kprobes: Prohibit probing on compiler generated CFI checking code Date: Mon, 10 Jul 2023 21:14:35 +0900 Message-Id: <168899127520.80889.15418363018799407058.stgit@devnote2> X-Mailer: git-send-email 2.25.1 In-Reply-To: <168899125356.80889.17967397360941194229.stgit@devnote2> References: <168899125356.80889.17967397360941194229.stgit@devnote2> User-Agent: StGit/0.19 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE 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: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771037202371841863 X-GMAIL-MSGID: 1771037202371841863 |
Series |
x86: kprobes: Fix CFI_CLANG related issues
|
|
Commit Message
Masami Hiramatsu (Google)
July 10, 2023, 12:14 p.m. UTC
From: Masami Hiramatsu (Google) <mhiramat@kernel.org> Prohibit probing on the compiler generated CFI typeid checking code because it is used for decoding typeid when CFI error happens. The compiler generates the following instruction sequence for indirect call checks on x86; movl -<id>, %r10d ; 6 bytes addl -4(%reg), %r10d ; 4 bytes je .Ltmp1 ; 2 bytes ud2 ; <- regs->ip And handle_cfi_failure() decodes these instructions (movl and addl) for the typeid and the target address. Thus if we put a kprobe on those instructions, the decode will fail and report a wrong typeid and target address. Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> --- arch/x86/kernel/kprobes/core.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)
Comments
On Mon, Jul 10, 2023 at 09:14:35PM +0900, Masami Hiramatsu (Google) wrote: > + if (IS_ENABLED(CONFIG_CFI_CLANG)) { > + /* > + * The compiler generates the following instruction sequence > + * for indirect call checks and cfi.c decodes this; > + * > + * movl -<id>, %r10d ; 6 bytes > + * addl -4(%reg), %r10d ; 4 bytes > + * je .Ltmp1 ; 2 bytes > + * ud2 ; <- regs->ip > + * .Ltmp1: > + * > + * Also, these movl and addl are used for showing expected > + * type. So those must not be touched. > + */ > + __addr = recover_probed_instruction(buf, addr); > + if (!__addr) > + return 0; > + > + if (insn_decode_kernel(&insn, (void *)__addr) < 0) > + return 0; > + > + if (insn.opcode.value == 0xBA) > + offset = 12; > + else if (insn.opcode.value == 0x3) > + offset = 6; > + else > + goto out; Notably, the JE will already be avoided? > + > + /* This movl/addl is used for decoding CFI. */ > + if (is_cfi_trap(addr + offset)) > + return 0; > + } > > +out: > return (addr == paddr); > } Hmm, so I was thinking something like the below, which also catches things when we rewrite kCFI to FineIBT, except I don't think we care if the FineIBT callsite gets re-written. FineIBT only relies on the __cfi_ symbol not getting poked at (which the previous patches should ensure). Additionally is_cfi_trap() is horrifically slow -- it's a full linear search of the entire kcfi_traps array, it doesn't have any smarts on (#UD can hardly be considered a fast path). So I tihnk I'm ok with the above, just adding the below for reference (completely untested and everything). Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> --- diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index f7f6042eb7e6..b812dee76909 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -293,6 +293,11 @@ static int can_probe(unsigned long paddr) #endif addr += insn.length; } + /* + * Don't allow poking the kCFI/FineIBT callsites. + */ + if (IS_ENABLED(CONFIG_CFI_CLANG) && cfi_call_site(addr)) + return 0; return (addr == paddr); } diff --git a/kernel/cfi.c b/kernel/cfi.c index 08caad776717..2656e6ffa013 100644 --- a/kernel/cfi.c +++ b/kernel/cfi.c @@ -31,16 +31,22 @@ static inline unsigned long trap_address(s32 *p) return (unsigned long)((long)p + (long)*p); } -static bool is_trap(unsigned long addr, s32 *start, s32 *end) +static long cfi_trap_distance(unsigned long addr, s32 *start, s32 *end) { + long dist = LONG_MAX; s32 *p; for (p = start; p < end; ++p) { - if (trap_address(p) == addr) - return true; + long d = trap_address(p) - addr; + + if (abs(dist) < abs(d)) { + dist = d; + if (dist == 0) + return 0; + } } - return false; + return dist; } #ifdef CONFIG_MODULES @@ -66,25 +72,25 @@ void module_cfi_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, } } -static bool is_module_cfi_trap(unsigned long addr) +static long module_cfi_trap_distance(unsigned long addr) { struct module *mod; - bool found = false; + long dist = LONG_MAX; rcu_read_lock_sched_notrace(); mod = __module_address(addr); if (mod) - found = is_trap(addr, mod->kcfi_traps, mod->kcfi_traps_end); + dist = cfi_trap_distance(addr, mod->kcfi_traps, mod->kcfi_traps_end); rcu_read_unlock_sched_notrace(); return found; } #else /* CONFIG_MODULES */ -static inline bool is_module_cfi_trap(unsigned long addr) +static long module_cfi_trap_distance(unsigned long addr) { - return false; + return LONG_MAX; } #endif /* CONFIG_MODULES */ @@ -93,9 +99,24 @@ extern s32 __stop___kcfi_traps[]; bool is_cfi_trap(unsigned long addr) { - if (is_trap(addr, __start___kcfi_traps, __stop___kcfi_traps)) + long dist = cfi_trap_distance(addr, __start___kcfi_traps, __stop___kcfi_traps); + if (!dist) + return true; + + return module_cfi_trap_distance(addr) == 0; +} + +bool cfi_call_site(unsigned long addr) +{ + long dist = cfi_trap_distance(addr, __start___kcfi_traps, __stop___kcfi_traps); + if (dist >= -12 && dist <= 0) + return true; + + dist = module_cfi_trap_distance(addr); + if (dist >= -12 && dist <= 0) return true; - return is_module_cfi_trap(addr); + return false; } + #endif /* CONFIG_ARCH_USES_CFI_TRAPS */
On Mon, Jul 10, 2023 at 06:16:43PM +0200, Peter Zijlstra wrote: > diff --git a/kernel/cfi.c b/kernel/cfi.c > index 08caad776717..2656e6ffa013 100644 > --- a/kernel/cfi.c > +++ b/kernel/cfi.c > @@ -31,16 +31,22 @@ static inline unsigned long trap_address(s32 *p) > return (unsigned long)((long)p + (long)*p); > } > > -static bool is_trap(unsigned long addr, s32 *start, s32 *end) > +static long cfi_trap_distance(unsigned long addr, s32 *start, s32 *end) > { > + long dist = LONG_MAX; > s32 *p; > > for (p = start; p < end; ++p) { > - if (trap_address(p) == addr) > - return true; > + long d = trap_address(p) - addr; > + > + if (abs(dist) < abs(d)) { Not that I expect anybody will care, but that should obviously be: abs(d) < abs(dist) > + dist = d; > + if (dist == 0) > + return 0; > + } > } > > - return false; > + return dist; > }
On Mon, 10 Jul 2023 18:16:43 +0200 Peter Zijlstra <peterz@infradead.org> wrote: > On Mon, Jul 10, 2023 at 09:14:35PM +0900, Masami Hiramatsu (Google) wrote: > > + if (IS_ENABLED(CONFIG_CFI_CLANG)) { > > + /* > > + * The compiler generates the following instruction sequence > > + * for indirect call checks and cfi.c decodes this; > > + * > > + * movl -<id>, %r10d ; 6 bytes > > + * addl -4(%reg), %r10d ; 4 bytes > > + * je .Ltmp1 ; 2 bytes > > + * ud2 ; <- regs->ip > > + * .Ltmp1: > > + * > > + * Also, these movl and addl are used for showing expected > > + * type. So those must not be touched. > > + */ > > + __addr = recover_probed_instruction(buf, addr); > > + if (!__addr) > > + return 0; > > + > > + if (insn_decode_kernel(&insn, (void *)__addr) < 0) > > + return 0; > > + > > + if (insn.opcode.value == 0xBA) > > + offset = 12; > > + else if (insn.opcode.value == 0x3) > > + offset = 6; > > + else > > + goto out; > > Notably, the JE will already be avoided? > > > + > > + /* This movl/addl is used for decoding CFI. */ > > + if (is_cfi_trap(addr + offset)) > > + return 0; > > + } > > > > +out: > > return (addr == paddr); > > } > > Hmm, so I was thinking something like the below, which also catches > things when we rewrite kCFI to FineIBT, except I don't think we care if > the FineIBT callsite gets re-written. FineIBT only relies on the __cfi_ > symbol not getting poked at (which the previous patches should ensure). Oh, is FineIBT different from kCFI? I thought those are same. But anyway for kCFI=y && FineIBT=n case, I think this code still needed. > > Additionally is_cfi_trap() is horrifically slow -- it's a full linear > search of the entire kcfi_traps array, it doesn't have any smarts on > (#UD can hardly be considered a fast path). Yeah, register_kprobe() is not a fast path in most cases. So I think this is OK at this point. We can speed it up by sorting the array by address and binary search later. > > So I tihnk I'm ok with the above, just adding the below for reference > (completely untested and everything). I wonder the distance can be used outside of x86. CFI implementation depends on the arch? > > > Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Thanks! > > > --- > diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c > index f7f6042eb7e6..b812dee76909 100644 > --- a/arch/x86/kernel/kprobes/core.c > +++ b/arch/x86/kernel/kprobes/core.c > @@ -293,6 +293,11 @@ static int can_probe(unsigned long paddr) > #endif > addr += insn.length; > } > + /* > + * Don't allow poking the kCFI/FineIBT callsites. > + */ > + if (IS_ENABLED(CONFIG_CFI_CLANG) && cfi_call_site(addr)) > + return 0; > > return (addr == paddr); > } > diff --git a/kernel/cfi.c b/kernel/cfi.c > index 08caad776717..2656e6ffa013 100644 > --- a/kernel/cfi.c > +++ b/kernel/cfi.c > @@ -31,16 +31,22 @@ static inline unsigned long trap_address(s32 *p) > return (unsigned long)((long)p + (long)*p); > } > > -static bool is_trap(unsigned long addr, s32 *start, s32 *end) > +static long cfi_trap_distance(unsigned long addr, s32 *start, s32 *end) > { > + long dist = LONG_MAX; > s32 *p; > > for (p = start; p < end; ++p) { > - if (trap_address(p) == addr) > - return true; > + long d = trap_address(p) - addr; > + > + if (abs(dist) < abs(d)) { > + dist = d; > + if (dist == 0) > + return 0; > + } > } > > - return false; > + return dist; > } > > #ifdef CONFIG_MODULES > @@ -66,25 +72,25 @@ void module_cfi_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, > } > } > > -static bool is_module_cfi_trap(unsigned long addr) > +static long module_cfi_trap_distance(unsigned long addr) > { > struct module *mod; > - bool found = false; > + long dist = LONG_MAX; > > rcu_read_lock_sched_notrace(); > > mod = __module_address(addr); > if (mod) > - found = is_trap(addr, mod->kcfi_traps, mod->kcfi_traps_end); > + dist = cfi_trap_distance(addr, mod->kcfi_traps, mod->kcfi_traps_end); > > rcu_read_unlock_sched_notrace(); > > return found; > } > #else /* CONFIG_MODULES */ > -static inline bool is_module_cfi_trap(unsigned long addr) > +static long module_cfi_trap_distance(unsigned long addr) > { > - return false; > + return LONG_MAX; > } > #endif /* CONFIG_MODULES */ > > @@ -93,9 +99,24 @@ extern s32 __stop___kcfi_traps[]; > > bool is_cfi_trap(unsigned long addr) > { > - if (is_trap(addr, __start___kcfi_traps, __stop___kcfi_traps)) > + long dist = cfi_trap_distance(addr, __start___kcfi_traps, __stop___kcfi_traps); > + if (!dist) > + return true; > + > + return module_cfi_trap_distance(addr) == 0; > +} > + > +bool cfi_call_site(unsigned long addr) > +{ > + long dist = cfi_trap_distance(addr, __start___kcfi_traps, __stop___kcfi_traps); > + if (dist >= -12 && dist <= 0) > + return true; > + > + dist = module_cfi_trap_distance(addr); > + if (dist >= -12 && dist <= 0) > return true; > > - return is_module_cfi_trap(addr); > + return false; > } > + > #endif /* CONFIG_ARCH_USES_CFI_TRAPS */
On Tue, Jul 11, 2023 at 08:58:37AM +0900, Masami Hiramatsu wrote: > Oh, is FineIBT different from kCFI? I thought those are same. But anyway > for kCFI=y && FineIBT=n case, I think this code still needed. Yeah, FineIBT relies on kCFI and IBT (and selects CALL_PADDING) and dynamically re-writes the kCFI infrastructure. All the gory details are in arch/x86/kernel/alternative.c, search for CONFIG_FINEIBT, I've tried to write a big comment, but please let me know if something isn't clear and I'll write some actual words :-). But basically kCFI is a pure software solution and does the check before the indirect control transfer (it has to). While FineIBT relies on the IBT hardware in order to do the check after. As such, FineIBT can do the CFI check without memory loads, which is good for performance. Another useful property of FineIBT is that it is a speculation barrier.
On Tue, Jul 11, 2023 at 08:58:37AM +0900, Masami Hiramatsu wrote: > > Hmm, so I was thinking something like the below, which also catches > > things when we rewrite kCFI to FineIBT, except I don't think we care if > > the FineIBT callsite gets re-written. FineIBT only relies on the __cfi_ > > symbol not getting poked at (which the previous patches should ensure). > > Oh, is FineIBT different from kCFI? I thought those are same. But anyway > for kCFI=y && FineIBT=n case, I think this code still needed. Ah, I forgot to answer your other question; FineIBT is dynamically patched since it relies on optional hardware features, only if the hardware has IBT support can FineIBT work. So yeah, your check is definitely needed. And I think it'll 'gracefully' fail when FineIBT is patched in because the instructions aren't exactly the same. And since FineIBT has most of the magic in the __cfi_ prefix, which isn't patched per the previous patch, I think we're good on the call-site. > > So I tihnk I'm ok with the above, just adding the below for reference > > (completely untested and everything). > > I wonder the distance can be used outside of x86. CFI implementation > depends on the arch? Currently only arm64 and x86_64 have CFI, and while the particulars are a little different, they do have a lot in common, including the reporting. IIRC the arm64 variant is a little simpler because of fixed instruction size. There is no worry someone will jump in the middle of an instruction stream.
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index f7f6042eb7e6..fa8c2b41cbaf 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -54,6 +54,7 @@ #include <asm/insn.h> #include <asm/debugreg.h> #include <asm/ibt.h> +#include <asm/cfi.h> #include "common.h" @@ -293,7 +294,40 @@ static int can_probe(unsigned long paddr) #endif addr += insn.length; } + if (IS_ENABLED(CONFIG_CFI_CLANG)) { + /* + * The compiler generates the following instruction sequence + * for indirect call checks and cfi.c decodes this; + * + * movl -<id>, %r10d ; 6 bytes + * addl -4(%reg), %r10d ; 4 bytes + * je .Ltmp1 ; 2 bytes + * ud2 ; <- regs->ip + * .Ltmp1: + * + * Also, these movl and addl are used for showing expected + * type. So those must not be touched. + */ + __addr = recover_probed_instruction(buf, addr); + if (!__addr) + return 0; + + if (insn_decode_kernel(&insn, (void *)__addr) < 0) + return 0; + + if (insn.opcode.value == 0xBA) + offset = 12; + else if (insn.opcode.value == 0x3) + offset = 6; + else + goto out; + + /* This movl/addl is used for decoding CFI. */ + if (is_cfi_trap(addr + offset)) + return 0; + } +out: return (addr == paddr); }