Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp341666pxv; Wed, 30 Jun 2021 06:55:22 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxcxR+iTviX2Ps2on/bRwYmtCEJVy+QbqmcXfYaxtSfafETz99psIyA8FvfazpywbeQVIBU X-Received: by 2002:a05:6e02:10c6:: with SMTP id s6mr909865ilj.175.1625061322056; Wed, 30 Jun 2021 06:55:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1625061322; cv=none; d=google.com; s=arc-20160816; b=r/CDkRSEX5D4mrwcsz1OB3fpsyo6bAQ3VQO5Y9tOusQ7yL0t4E6Tr9MRXalnPcRc1x UVN1wDTwaBHKXcmG/LFEDj2HgGaLuizBhaqM+xvkTnvLMo2nRXBrlRER/KQlMlLMlMMA zToyvAXg9Yk7DWW9JZjZjsDLYHfTqxTExsXLV/YvZpa6vu9ejjHoa4xyEBwY/2btzUDA HdV3FiUzgKV8ZT0HP32HvSAxhZRMbnQYFMRIRU7FmiuToKHeYoHuL9vmWPZZ1wfIOwfN leW2wKaaf48XU9JsMd2ZCE5r+uqbRiLQrLO/lwwvZUSM64XYFs1Rc93ipxb2vlNHEKuZ LLDg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:robot-unsubscribe :robot-id:message-id:mime-version:cc:subject:to:reply-to:sender:from :dkim-signature:dkim-signature:date; bh=RiBTXM3AqT1R5ffR45UV7ZMF3xcMw/MCd802PvzPjXM=; b=jvHJMpaR7WdBadCcTZaHDM+BHBIdpsMsmn10OCQ95W1MQINWafpvODRg5+AJ0e/XEw mift3GLvRxSOy7/kLpGyy8zZKw75H6ArfKiUurlQRgGAdyid56duSeRk2MPx4LjjkPue S2lUoYrfJfwXex/C4c1E9AjCIcfzyFWrzgJTrFTlsgm7QPgof0Tk+fVmaSWaqtjFKGO3 vUgD+HdpslkFQQWd9PKau+0gdSO7BJsql1iWG2jG0/05VsOzS1QE1McRalR8BI5zv2KJ QcU67CF2cBh9rhUxfxoPzzC67PyIGCLK179TAdntn5HYe5mZl8C6mztdLmfZmcfYRbhS qRdQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=DAN7AlNx; dkim=neutral (no key) header.i=@linutronix.de; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id q13si4052559ilo.28.2021.06.30.06.55.10; Wed, 30 Jun 2021 06:55:22 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=DAN7AlNx; dkim=neutral (no key) header.i=@linutronix.de; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236652AbhF3Nz1 (ORCPT + 99 others); Wed, 30 Jun 2021 09:55:27 -0400 Received: from Galois.linutronix.de ([193.142.43.55]:33022 "EHLO galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236130AbhF3NvY (ORCPT ); Wed, 30 Jun 2021 09:51:24 -0400 Date: Wed, 30 Jun 2021 13:48:17 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1625060897; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=RiBTXM3AqT1R5ffR45UV7ZMF3xcMw/MCd802PvzPjXM=; b=DAN7AlNxalj/uz4di5IjMT4cJqCi4/NGMHCOTZrlVw5GDrycObv09zmkdH3KlG2486/GmG kHdHYctsYx/vfZGTQo3JSre9Tla3EAUysyMqxgm1zcnRdvDcye80zgd1zAkxcanldeZzNf lAvSExYL+pAXE4eX4QbU2T9bRCV7EnBSUu+840Uj0d+nNdEGXkplqL8LeBwOeQuvlaHVq7 4+QRK+N8UtsReMnlkszvi68w0/tGtYqZs2xSUoEu212w9l3ikdUzKTtJsXZyoy48ZgNahE 6L3VMjSxlBzXwCZVNzsclC/ksnxQnfwQHHTN3bOq+wqfSw4PTZfJn48wBDFsbg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1625060897; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=RiBTXM3AqT1R5ffR45UV7ZMF3xcMw/MCd802PvzPjXM=; b=7kyz7H7Fpi0nl5JNrx7Ggrr8jgVI7dKOBoJZkV8ZVL7+5qDv9nUI2luXGsb7FJHQmLVizy UYJcGGBXKUyYBLBw== From: "tip-bot2 for Mark Rutland" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: locking/urgent] kcsan: Report observed value changes Cc: Mark Rutland , Marco Elver , "Paul E. McKenney" , x86@kernel.org, linux-kernel@vger.kernel.org MIME-Version: 1.0 Message-ID: <162506089714.395.6467456436207971619.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The following commit has been merged into the locking/urgent branch of tip: Commit-ID: 7bbe6dc0ade7e394ee1568dc9979fd0e3e155435 Gitweb: https://git.kernel.org/tip/7bbe6dc0ade7e394ee1568dc9979fd0e3e155435 Author: Mark Rutland AuthorDate: Wed, 14 Apr 2021 13:28:24 +02:00 Committer: Paul E. McKenney CommitterDate: Tue, 18 May 2021 10:58:15 -07:00 kcsan: Report observed value changes When a thread detects that a memory location was modified without its watchpoint being hit, the report notes that a change was detected, but does not provide concrete values for the change. Knowing the concrete values can be very helpful in tracking down any racy writers (e.g. as specific values may only be written in some portions of code, or under certain conditions). When we detect a modification, let's report the concrete old/new values, along with the access's mask of relevant bits (and which relevant bits were modified). This can make it easier to identify potential racy writers. As the snapshots are at most 8 bytes, we can only report values for acceses up to this size, but this appears to cater for the common case. When we detect a race via a watchpoint, we may or may not have concrete values for the modification. To be helpful, let's attempt to log them when we do as they can be ignored where irrelevant. The resulting reports appears as follows, with values zero-padded to the access width: | ================================================================== | BUG: KCSAN: data-race in el0_svc_common+0x34/0x25c arch/arm64/kernel/syscall.c:96 | | race at unknown origin, with read to 0xffff00007ae6aa00 of 8 bytes by task 223 on cpu 1: | el0_svc_common+0x34/0x25c arch/arm64/kernel/syscall.c:96 | do_el0_svc+0x48/0xec arch/arm64/kernel/syscall.c:178 | el0_svc arch/arm64/kernel/entry-common.c:226 [inline] | el0_sync_handler+0x1a4/0x390 arch/arm64/kernel/entry-common.c:236 | el0_sync+0x140/0x180 arch/arm64/kernel/entry.S:674 | | value changed: 0x0000000000000000 -> 0x0000000000000002 | | Reported by Kernel Concurrency Sanitizer on: | CPU: 1 PID: 223 Comm: syz-executor.1 Not tainted 5.8.0-rc3-00094-ga73f923ecc8e-dirty #3 | Hardware name: linux,dummy-virt (DT) | ================================================================== If an access mask is set, it is shown underneath the "value changed" line as "bits changed: 0x with mask 0x". Signed-off-by: Mark Rutland [ elver@google.com: align "value changed" and "bits changed" lines, which required massaging the message; do not print bits+mask if no mask set. ] Signed-off-by: Marco Elver Signed-off-by: Paul E. McKenney --- kernel/kcsan/core.c | 5 +++-- kernel/kcsan/kcsan.h | 6 ++++-- kernel/kcsan/report.c | 31 ++++++++++++++++++++++++++----- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/kernel/kcsan/core.c b/kernel/kcsan/core.c index 6fe1513..26709ea 100644 --- a/kernel/kcsan/core.c +++ b/kernel/kcsan/core.c @@ -557,7 +557,8 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) atomic_long_inc(&kcsan_counters[KCSAN_COUNTER_ASSERT_FAILURES]); kcsan_report_known_origin(ptr, size, type, value_change, - watchpoint - watchpoints); + watchpoint - watchpoints, + old, new, access_mask); } else if (value_change == KCSAN_VALUE_CHANGE_TRUE) { /* Inferring a race, since the value should not have changed. */ @@ -566,7 +567,7 @@ kcsan_setup_watchpoint(const volatile void *ptr, size_t size, int type) atomic_long_inc(&kcsan_counters[KCSAN_COUNTER_ASSERT_FAILURES]); if (IS_ENABLED(CONFIG_KCSAN_REPORT_RACE_UNKNOWN_ORIGIN) || is_assert) - kcsan_report_unknown_origin(ptr, size, type); + kcsan_report_unknown_origin(ptr, size, type, old, new, access_mask); } /* diff --git a/kernel/kcsan/kcsan.h b/kernel/kcsan/kcsan.h index 572f119..f36e25c 100644 --- a/kernel/kcsan/kcsan.h +++ b/kernel/kcsan/kcsan.h @@ -129,12 +129,14 @@ void kcsan_report_set_info(const volatile void *ptr, size_t size, int access_typ * thread. */ void kcsan_report_known_origin(const volatile void *ptr, size_t size, int access_type, - enum kcsan_value_change value_change, int watchpoint_idx); + enum kcsan_value_change value_change, int watchpoint_idx, + u64 old, u64 new, u64 mask); /* * No other thread was observed to race with the access, but the data value * before and after the stall differs. Reports a race of "unknown origin". */ -void kcsan_report_unknown_origin(const volatile void *ptr, size_t size, int access_type); +void kcsan_report_unknown_origin(const volatile void *ptr, size_t size, int access_type, + u64 old, u64 new, u64 mask); #endif /* _KERNEL_KCSAN_KCSAN_H */ diff --git a/kernel/kcsan/report.c b/kernel/kcsan/report.c index 50cee23..e37e438 100644 --- a/kernel/kcsan/report.c +++ b/kernel/kcsan/report.c @@ -327,7 +327,8 @@ static void print_verbose_info(struct task_struct *task) static void print_report(enum kcsan_value_change value_change, const struct access_info *ai, - const struct other_info *other_info) + const struct other_info *other_info, + u64 old, u64 new, u64 mask) { unsigned long stack_entries[NUM_STACK_ENTRIES] = { 0 }; int num_stack_entries = stack_trace_save(stack_entries, NUM_STACK_ENTRIES, 1); @@ -407,6 +408,24 @@ static void print_report(enum kcsan_value_change value_change, if (IS_ENABLED(CONFIG_KCSAN_VERBOSE)) print_verbose_info(current); + /* Print observed value change. */ + if (ai->size <= 8) { + int hex_len = ai->size * 2; + u64 diff = old ^ new; + + if (mask) + diff &= mask; + if (diff) { + pr_err("\n"); + pr_err("value changed: 0x%0*llx -> 0x%0*llx\n", + hex_len, old, hex_len, new); + if (mask) { + pr_err(" bits changed: 0x%0*llx with mask 0x%0*llx\n", + hex_len, diff, hex_len, mask); + } + } + } + /* Print report footer. */ pr_err("\n"); pr_err("Reported by Kernel Concurrency Sanitizer on:\n"); @@ -584,7 +603,8 @@ void kcsan_report_set_info(const volatile void *ptr, size_t size, int access_typ } void kcsan_report_known_origin(const volatile void *ptr, size_t size, int access_type, - enum kcsan_value_change value_change, int watchpoint_idx) + enum kcsan_value_change value_change, int watchpoint_idx, + u64 old, u64 new, u64 mask) { const struct access_info ai = prepare_access_info(ptr, size, access_type); struct other_info *other_info = &other_infos[watchpoint_idx]; @@ -608,7 +628,7 @@ void kcsan_report_known_origin(const volatile void *ptr, size_t size, int access * be done once we know the full stack trace in print_report(). */ if (value_change != KCSAN_VALUE_CHANGE_FALSE) - print_report(value_change, &ai, other_info); + print_report(value_change, &ai, other_info, old, new, mask); release_report(&flags, other_info); out: @@ -616,7 +636,8 @@ out: kcsan_enable_current(); } -void kcsan_report_unknown_origin(const volatile void *ptr, size_t size, int access_type) +void kcsan_report_unknown_origin(const volatile void *ptr, size_t size, int access_type, + u64 old, u64 new, u64 mask) { const struct access_info ai = prepare_access_info(ptr, size, access_type); unsigned long flags; @@ -625,7 +646,7 @@ void kcsan_report_unknown_origin(const volatile void *ptr, size_t size, int acce lockdep_off(); /* See kcsan_report_known_origin(). */ raw_spin_lock_irqsave(&report_lock, flags); - print_report(KCSAN_VALUE_CHANGE_TRUE, &ai, NULL); + print_report(KCSAN_VALUE_CHANGE_TRUE, &ai, NULL, old, new, mask); raw_spin_unlock_irqrestore(&report_lock, flags); lockdep_on();