Message ID | 20221118172305.3321253-1-glider@google.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp321963wrr; Fri, 18 Nov 2022 09:34:13 -0800 (PST) X-Google-Smtp-Source: AA0mqf6zUwNxBlX8o5t2F5GFYZX4DNDgeCsU8pd2+Q9i8CyXsQWP3ePQes3/zKBujv1xLj0xPFYZ X-Received: by 2002:a63:4b1d:0:b0:476:837c:e0a with SMTP id y29-20020a634b1d000000b00476837c0e0amr7538160pga.411.1668792852974; Fri, 18 Nov 2022 09:34:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668792852; cv=none; d=google.com; s=arc-20160816; b=ei2OxNcPKqdCPN1nMUUKFMYUwF6qTb8rC+cJaV98ZIJkKKmy0lq7H1jYHjvBXrkhdS r5EWrZwXvEc9vp5lhevkHV8AUpmCpCpnzbt9gM31oggJOQWQH7ie2FmQV9VTFn86SzJo GqNGAN48salmVJHQnGVA6RP5AWlYTmxOnk8/pmT+wYFBXfe05XBimY3nEsfZZLSdUH6u HOYwkH+754+dvC+cpPk81/UWwPPb+08qyLFqbB8yDOoTUYmnckI8gNAtZKRRtpevKJP/ KPaJ57jqRg7X6kKPdeH3/hpF3Q6MNyzPdRm6kVp7MrJ7qWt5qLpE4gk9biU/VUcOWHjJ x+Sw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:message-id:mime-version:date :dkim-signature; bh=e+LcyMNkInxJbEkI4dZYVXRRy3OSinTohFLJ8BhSGEI=; b=u8GtkGVXQlgbW421IyfiHpzRZkvJV0IAH5MJE4830acOaAizsKHO7lSLu/x7ZrAx9E ipI9ag3e3VfHZzQrN79kLXhHV6MA7eDduXzOlylYZdbOUQALwO0Dzlkrucq6HsPsr3OI qBr11XFH9sJoJg59I6p+O7Qc6CHDCQhKRU0lWatHE77OT4A266HWkay2mV6+8zzppUnO 60g7GCDVUKfzCuUsTPlFgTHLqqxrw2HRGrhEtAIUdr5T95WsP777b9v+bbO4g8kY51a2 MyLAoMrxmMnSaqaE5XKJeK4ThJzS2STXE6pF1b/Iw+KnFIc0yyAcmowbkTMnSCma7kPK p7Vg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=Wl236N0E; 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=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id oc1-20020a17090b1c0100b00214240419d1si4646878pjb.3.2022.11.18.09.33.58; Fri, 18 Nov 2022 09:34:12 -0800 (PST) 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=@google.com header.s=20210112 header.b=Wl236N0E; 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=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242491AbiKRRXO (ORCPT <rfc822;kkmonlee@gmail.com> + 99 others); Fri, 18 Nov 2022 12:23:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56072 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234973AbiKRRXM (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Fri, 18 Nov 2022 12:23:12 -0500 Received: from mail-ej1-x64a.google.com (mail-ej1-x64a.google.com [IPv6:2a00:1450:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9A9562F03B for <linux-kernel@vger.kernel.org>; Fri, 18 Nov 2022 09:23:11 -0800 (PST) Received: by mail-ej1-x64a.google.com with SMTP id sd31-20020a1709076e1f00b007ae63b8d66aso3376923ejc.3 for <linux-kernel@vger.kernel.org>; Fri, 18 Nov 2022 09:23:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:mime-version:date:from:to:cc:subject :date:message-id:reply-to; bh=e+LcyMNkInxJbEkI4dZYVXRRy3OSinTohFLJ8BhSGEI=; b=Wl236N0EDKtBFLF3ZJNWeD3tjBamKSe4XEAfRsjqhhj+klve+os4bfTYg83EIPQ/4Q hp+cnUMvnITTbvKaNTXl07JdHoz+lGr+X/aXxb52r7wymAxIwAIlxeIHxKP3vsHuijiw eKuG/BOL2Jok/B9WT8pPYUhfJYFKk38jGlzqBHlvKuiGPUu5XDHXAr2LPnEu6Rloyt+W JCjDKRBdf8/ZZBamqF8rAC0KvR9N6tjia/WnhQgoFQE0X2V9opZjTcdwxnqaV7Xt8Hv1 q3fTPwUJeU8+AFSdVnASzguBS9QvQSpSqKPMg0TiRl+NXPG7ObOlcOmYUwi6HWl/BBfB dm2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=e+LcyMNkInxJbEkI4dZYVXRRy3OSinTohFLJ8BhSGEI=; b=BzjThSeC2mL63ERPJbI8Fs212tyXV+Q5LFhfqm8sh+JrOqja+N63NchOHoGNoZS9Av 8rz+kF0gQ5aREU4hqjnzyH8iTR982qlzULn4ymD+FVJz60tpiMqbdjiijkMiM1eqxr8J gM7XF2F99IUz11MZPxRvGQB+lWx0ZEryHe0/zrwYnxX77+YkqUDYiOZYsWhY94lrRcHi 9u9MT5hhS7jDNjlb2sPaGh3tV9qeBxsi7HEg8YkzD9rzQK3TTjBaDi/4P2MPLZO35LSf k1jPHiE3WDFqpGjn3DxLuGmzGLSz46NpF1lm9lCPn9Yo8I3YFl9T7CXQrlqchI2cEDl2 KB1g== X-Gm-Message-State: ANoB5pli/miXVX9RHL+1xSKVFTFGDraUNy9G+3SUKXgSQcpDU+j9FwFt Se58acC7KecpBBruW4rnsIhzX6p1kWI= X-Received: from glider.muc.corp.google.com ([2a00:79e0:9c:201:ec10:bae8:fee8:751d]) (user=glider job=sendgmr) by 2002:a17:906:1188:b0:7b2:c594:2182 with SMTP id n8-20020a170906118800b007b2c5942182mr2246482eja.290.1668792190132; Fri, 18 Nov 2022 09:23:10 -0800 (PST) Date: Fri, 18 Nov 2022 18:23:05 +0100 Mime-Version: 1.0 X-Mailer: git-send-email 2.38.1.584.g0f3c55d4c2-goog Message-ID: <20221118172305.3321253-1-glider@google.com> Subject: [PATCH] x86: suppress KMSAN reports in arch_within_stack_frames() From: Alexander Potapenko <glider@google.com> To: glider@google.com Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, linux-kernel@vger.kernel.org, Eric Biggers <ebiggers@kernel.org> Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL 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: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749856134272646349?= X-GMAIL-MSGID: =?utf-8?q?1749856134272646349?= |
Series |
x86: suppress KMSAN reports in arch_within_stack_frames()
|
|
Commit Message
Alexander Potapenko
Nov. 18, 2022, 5:23 p.m. UTC
arch_within_stack_frames() performs stack walking and may confuse
KMSAN by stepping on stale shadow values. To prevent false positive
reports, disable KMSAN checks in this function.
This fixes KMSAN's interoperability with CONFIG_HARDENED_USERCOPY.
Link: https://github.com/google/kmsan/issues/89
Link: https://lore.kernel.org/lkml/Y3b9AAEKp2Vr3e6O@sol.localdomain/
Cc: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Alexander Potapenko <glider@google.com>
---
arch/x86/include/asm/thread_info.h | 5 +++++
1 file changed, 5 insertions(+)
Comments
On Fri, Nov 18, 2022 at 06:23:05PM +0100, Alexander Potapenko wrote: > arch_within_stack_frames() performs stack walking and may confuse > KMSAN by stepping on stale shadow values. To prevent false positive > reports, disable KMSAN checks in this function. > > This fixes KMSAN's interoperability with CONFIG_HARDENED_USERCOPY. > > Link: https://github.com/google/kmsan/issues/89 > Link: https://lore.kernel.org/lkml/Y3b9AAEKp2Vr3e6O@sol.localdomain/ > Cc: Eric Biggers <ebiggers@kernel.org> > Signed-off-by: Alexander Potapenko <glider@google.com> > --- > arch/x86/include/asm/thread_info.h | 5 +++++ > 1 file changed, 5 insertions(+) > > diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h > index f0cb881c1d690..f1cccba52eb97 100644 > --- a/arch/x86/include/asm/thread_info.h > +++ b/arch/x86/include/asm/thread_info.h > @@ -163,7 +163,12 @@ struct thread_info { > * GOOD_FRAME if within a frame > * BAD_STACK if placed across a frame boundary (or outside stack) > * NOT_STACK unable to determine (no frame pointers, etc) > + * > + * This function reads pointers from the stack and dereferences them. The > + * pointers may not have their KMSAN shadow set up properly, which may result > + * in false positive reports. Disable instrumentation to avoid those. > */ > +__no_kmsan_checks > static inline int arch_within_stack_frames(const void * const stack, > const void * const stackend, > const void *obj, unsigned long len) Seems OK; but now I'm confused as to the exact distinction between __no_sanitize_memory and __no_kmsan_checks. The comments there about seem to suggest __no_sanitize_memory ensures no instrumentation at all, and __no_kmsan_checks some instrumentation but doesn't actually check anything -- so what's left then?
On Mon, Nov 21, 2022 at 11:23 AM Peter Zijlstra <peterz@infradead.org> wrote: > > On Fri, Nov 18, 2022 at 06:23:05PM +0100, Alexander Potapenko wrote: > > arch_within_stack_frames() performs stack walking and may confuse > > KMSAN by stepping on stale shadow values. To prevent false positive > > reports, disable KMSAN checks in this function. > > > > This fixes KMSAN's interoperability with CONFIG_HARDENED_USERCOPY. > > > > Link: https://github.com/google/kmsan/issues/89 > > Link: https://lore.kernel.org/lkml/Y3b9AAEKp2Vr3e6O@sol.localdomain/ > > Cc: Eric Biggers <ebiggers@kernel.org> > > Signed-off-by: Alexander Potapenko <glider@google.com> > > --- > > arch/x86/include/asm/thread_info.h | 5 +++++ > > 1 file changed, 5 insertions(+) > > > > diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h > > index f0cb881c1d690..f1cccba52eb97 100644 > > --- a/arch/x86/include/asm/thread_info.h > > +++ b/arch/x86/include/asm/thread_info.h > > @@ -163,7 +163,12 @@ struct thread_info { > > * GOOD_FRAME if within a frame > > * BAD_STACK if placed across a frame boundary (or outside stack) > > * NOT_STACK unable to determine (no frame pointers, etc) > > + * > > + * This function reads pointers from the stack and dereferences them. The > > + * pointers may not have their KMSAN shadow set up properly, which may result > > + * in false positive reports. Disable instrumentation to avoid those. > > */ > > +__no_kmsan_checks > > static inline int arch_within_stack_frames(const void * const stack, > > const void * const stackend, > > const void *obj, unsigned long len) > > Seems OK; but now I'm confused as to the exact distinction between > __no_sanitize_memory and __no_kmsan_checks. > > The comments there about seem to suggest __no_sanitize_memory ensures no > instrumentation at all, and __no_kmsan_checks some instrumentation but > doesn't actually check anything -- so what's left then? __no_sanitize_memory prohibits all instrumentation whatsoever, whereas __no_kmsan_checks adds instrumentation that suppresses potential false positives around this function. Quoting include/linux/compiler-clang.h: /* * The __no_kmsan_checks attribute ensures that a function does not produce * false positive reports by: * - initializing all local variables and memory stores in this function; * - skipping all shadow checks; * - passing initialized arguments to this function's callees. */ Does this answer your question?
On Mon, Nov 21, 2022 at 11:28:39AM +0100, Alexander Potapenko wrote: > > > +__no_kmsan_checks > > > static inline int arch_within_stack_frames(const void * const stack, > > > const void * const stackend, > > > const void *obj, unsigned long len) > > > > Seems OK; but now I'm confused as to the exact distinction between > > __no_sanitize_memory and __no_kmsan_checks. > > > > The comments there about seem to suggest __no_sanitize_memory ensures no > > instrumentation at all, and __no_kmsan_checks some instrumentation but > > doesn't actually check anything -- so what's left then? > > __no_sanitize_memory prohibits all instrumentation whatsoever, whereas > __no_kmsan_checks adds instrumentation that suppresses potential false > positives around this function. > > Quoting include/linux/compiler-clang.h: > > /* > * The __no_kmsan_checks attribute ensures that a function does not produce > * false positive reports by: > * - initializing all local variables and memory stores in this function; > * - skipping all shadow checks; > * - passing initialized arguments to this function's callees. > */ > > Does this answer your question? So I read that comment; and it didn't click. So you're explicitly initializing variables/arguments and explicitly not checking shadow state vs, not doing explicit initialization and checking shadow state? That is, it doesn't do the normal checks and adds explicit initialization to avoid triggering discontent in surrounding functions?
On Mon, Nov 21, 2022 at 12:38 PM Peter Zijlstra <peterz@infradead.org> wrote: > > On Mon, Nov 21, 2022 at 11:28:39AM +0100, Alexander Potapenko wrote: > > > > > +__no_kmsan_checks > > > > static inline int arch_within_stack_frames(const void * const stack, > > > > const void * const stackend, > > > > const void *obj, unsigned long len) > > > > > > Seems OK; but now I'm confused as to the exact distinction between > > > __no_sanitize_memory and __no_kmsan_checks. > > > > > > The comments there about seem to suggest __no_sanitize_memory ensures no > > > instrumentation at all, and __no_kmsan_checks some instrumentation but > > > doesn't actually check anything -- so what's left then? > > > > __no_sanitize_memory prohibits all instrumentation whatsoever, whereas > > __no_kmsan_checks adds instrumentation that suppresses potential false > > positives around this function. > > > > Quoting include/linux/compiler-clang.h: > > > > /* > > * The __no_kmsan_checks attribute ensures that a function does not produce > > * false positive reports by: > > * - initializing all local variables and memory stores in this function; > > * - skipping all shadow checks; > > * - passing initialized arguments to this function's callees. > > */ > > > > Does this answer your question? > > So I read that comment; and it didn't click. So you're explicitly > initializing variables/arguments and explicitly not checking shadow > state vs, not doing explicit initialization and checking shadow state? > > That is, it doesn't do the normal checks and adds explicit > initialization to avoid triggering discontent in surrounding functions? > Correct In other words, for normal instrumentation: - locals are explicitly marked as uninitialized; - shadow values are calculated for arithmetic operations based on their inputs; - shadow values are checked for branches, pointer dereferences, and before passing them as function arguments; - memory stores update shadow for affected variables. For __no_kmsan_checks: - locals are explicitly marked as initialized; - no instrumentation is added for arithmetic operations, branches, pointer dereferences; - all function arguments are marked as initialized; - stores always mark memory as initialized. For __no_sanitize_memory: - no instrumentation for locals (they may end up being initialized or uninitialized - doesn't matter, because their shadow values are never used); - no instrumentation for arithmetic operations, branches, pointer dereferences; - no instrumentation for function calls (an instrumented function will receive garbage shadow values from a non-instrumented one); - no instrumentation for stores (initialization done in these functions is invisible). In all the cases explicit calls to kmsan_poison_memory()/kmsan_unpoison_memory()/kmsan_check_memory() behave the same way and can be used to tell the tool what is going on in the absence of instrumentation.
On Mon, Nov 21, 2022 at 03:27:49PM +0100, Alexander Potapenko wrote: > In other words, for normal instrumentation: > - locals are explicitly marked as uninitialized; > - shadow values are calculated for arithmetic operations based on their inputs; > - shadow values are checked for branches, pointer dereferences, and > before passing them as function arguments; > - memory stores update shadow for affected variables. > > For __no_kmsan_checks: > - locals are explicitly marked as initialized; > - no instrumentation is added for arithmetic operations, branches, > pointer dereferences; > - all function arguments are marked as initialized; > - stores always mark memory as initialized. > > For __no_sanitize_memory: > - no instrumentation for locals (they may end up being initialized or > uninitialized - doesn't matter, because their shadow values are never > used); > - no instrumentation for arithmetic operations, branches, pointer dereferences; > - no instrumentation for function calls (an instrumented function > will receive garbage shadow values from a non-instrumented one); > - no instrumentation for stores (initialization done in these > functions is invisible). Thanks! That is a great summary.
On Fri, Nov 18, 2022 at 06:23:05PM +0100, Alexander Potapenko wrote: > arch_within_stack_frames() performs stack walking and may confuse > KMSAN by stepping on stale shadow values. To prevent false positive > reports, disable KMSAN checks in this function. > > This fixes KMSAN's interoperability with CONFIG_HARDENED_USERCOPY. > > Link: https://github.com/google/kmsan/issues/89 > Link: https://lore.kernel.org/lkml/Y3b9AAEKp2Vr3e6O@sol.localdomain/ > Cc: Eric Biggers <ebiggers@kernel.org> > Signed-off-by: Alexander Potapenko <glider@google.com> > --- > arch/x86/include/asm/thread_info.h | 5 +++++ > 1 file changed, 5 insertions(+) Tested-by: Eric Biggers <ebiggers@google.com> - Eric
On Tue, Nov 29, 2022 at 09:40:45PM -0800, Eric Biggers wrote: > On Fri, Nov 18, 2022 at 06:23:05PM +0100, Alexander Potapenko wrote: > > arch_within_stack_frames() performs stack walking and may confuse > > KMSAN by stepping on stale shadow values. To prevent false positive > > reports, disable KMSAN checks in this function. > > > > This fixes KMSAN's interoperability with CONFIG_HARDENED_USERCOPY. > > > > Link: https://github.com/google/kmsan/issues/89 > > Link: https://lore.kernel.org/lkml/Y3b9AAEKp2Vr3e6O@sol.localdomain/ > > Cc: Eric Biggers <ebiggers@kernel.org> > > Signed-off-by: Alexander Potapenko <glider@google.com> > > --- > > arch/x86/include/asm/thread_info.h | 5 +++++ > > 1 file changed, 5 insertions(+) > > Tested-by: Eric Biggers <ebiggers@google.com> > Can this patch be applied to the x86 tree, please? - Eric
On Wed, Jan 11, 2023 at 09:40:47PM -0800, Eric Biggers wrote: > On Tue, Nov 29, 2022 at 09:40:45PM -0800, Eric Biggers wrote: > > On Fri, Nov 18, 2022 at 06:23:05PM +0100, Alexander Potapenko wrote: > > > arch_within_stack_frames() performs stack walking and may confuse > > > KMSAN by stepping on stale shadow values. To prevent false positive > > > reports, disable KMSAN checks in this function. > > > > > > This fixes KMSAN's interoperability with CONFIG_HARDENED_USERCOPY. > > > > > > Link: https://github.com/google/kmsan/issues/89 > > > Link: https://lore.kernel.org/lkml/Y3b9AAEKp2Vr3e6O@sol.localdomain/ > > > Cc: Eric Biggers <ebiggers@kernel.org> > > > Signed-off-by: Alexander Potapenko <glider@google.com> > > > --- > > > arch/x86/include/asm/thread_info.h | 5 +++++ > > > 1 file changed, 5 insertions(+) > > > > Tested-by: Eric Biggers <ebiggers@google.com> > > > > Can this patch be applied to the x86 tree, please? > > - Eric Ping.
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index f0cb881c1d690..f1cccba52eb97 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -163,7 +163,12 @@ struct thread_info { * GOOD_FRAME if within a frame * BAD_STACK if placed across a frame boundary (or outside stack) * NOT_STACK unable to determine (no frame pointers, etc) + * + * This function reads pointers from the stack and dereferences them. The + * pointers may not have their KMSAN shadow set up properly, which may result + * in false positive reports. Disable instrumentation to avoid those. */ +__no_kmsan_checks static inline int arch_within_stack_frames(const void * const stack, const void * const stackend, const void *obj, unsigned long len)