From: Will Deacon <will@kernel.org>
To: linux-kernel@vger.kernel.org
Cc: Will Deacon <will@kernel.org>, Eric Dumazet <edumazet@google.com>,
Jann Horn <jannh@google.com>, Kees Cook <keescook@chromium.org>,
Maddie Stone <maddiestone@google.com>,
Marco Elver <elver@google.com>,
"Paul E . McKenney" <paulmck@kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
Thomas Gleixner <tglx@linutronix.de>,
kernel-team@android.com, kernel-hardening@lists.openwall.com
Subject: [RFC PATCH 04/21] timers: Use hlist_unhashed() instead of open-coding in timer_pending()
Date: Tue, 24 Mar 2020 15:36:26 +0000 [thread overview]
Message-ID: <20200324153643.15527-5-will@kernel.org> (raw)
In-Reply-To: <20200324153643.15527-1-will@kernel.org>
timer_pending() open-codes a version of hlist_unhashed() to check
whether or not the 'timer' parameter has been queued in the timer wheel.
KCSAN detects this as a racy operation and explodes at us:
| BUG: KCSAN: data-race in del_timer / detach_if_pending
|
| write to 0xffff88808697d870 of 8 bytes by task 10 on cpu 0:
| __hlist_del include/linux/list.h:764 [inline]
| detach_timer kernel/time/timer.c:815 [inline]
| detach_if_pending+0xcd/0x2d0 kernel/time/timer.c:832
| try_to_del_timer_sync+0x60/0xb0 kernel/time/timer.c:1226
| del_timer_sync+0x6b/0xa0 kernel/time/timer.c:1365
| schedule_timeout+0x2d2/0x6e0 kernel/time/timer.c:1896
| rcu_gp_fqs_loop+0x37c/0x580 kernel/rcu/tree.c:1639
| rcu_gp_kthread+0x143/0x230 kernel/rcu/tree.c:1799
| kthread+0x1d4/0x200 drivers/block/aoe/aoecmd.c:1253
| ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:352
|
| read to 0xffff88808697d870 of 8 bytes by task 12060 on cpu 1:
| del_timer+0x3b/0xb0 kernel/time/timer.c:1198
| sk_stop_timer+0x25/0x60 net/core/sock.c:2845
| inet_csk_clear_xmit_timers+0x69/0xa0 net/ipv4/inet_connection_sock.c:523
| tcp_clear_xmit_timers include/net/tcp.h:606 [inline]
| tcp_v4_destroy_sock+0xa3/0x3f0 net/ipv4/tcp_ipv4.c:2096
| inet_csk_destroy_sock+0xf4/0x250 net/ipv4/inet_connection_sock.c:836
| tcp_close+0x6f3/0x970 net/ipv4/tcp.c:2497
| inet_release+0x86/0x100 net/ipv4/af_inet.c:427
| __sock_release+0x85/0x160 net/socket.c:590
| sock_close+0x24/0x30 net/socket.c:1268
| __fput+0x1e1/0x520 fs/file_table.c:280
| ____fput+0x1f/0x30 fs/file_table.c:313
| task_work_run+0xf6/0x130 kernel/task_work.c:113
| tracehook_notify_resume include/linux/tracehook.h:188 [inline]
| exit_to_usermode_loop+0x2b4/0x2c0 arch/x86/entry/common.c:163
Replace the explicit 'pprev' pointer comparison in timer_pending() with
a call to hlist_unhashed() and initialise the 'expires' timer field
explicitly in do_init_timer() so that the compiler doesn't emit bogus
'maybe used uninitialised' warnings now that it cannot reason statically
about the result of timer_pending().
Cc: Paul E. McKenney <paulmck@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: Will Deacon <will@kernel.org>
---
include/linux/timer.h | 5 +++--
kernel/time/timer.c | 1 +
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 1e6650ed066d..e9610d2988ba 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -158,13 +158,14 @@ static inline void destroy_timer_on_stack(struct timer_list *timer) { }
*
* timer_pending will tell whether a given timer is currently pending,
* or not. Callers must ensure serialization wrt. other operations done
- * to this timer, eg. interrupt contexts, or other CPUs on SMP.
+ * to this timer, eg. interrupt contexts, or other CPUs on SMP if they
+ * cannot tolerate spurious results.
*
* return value: 1 if the timer is pending, 0 if not.
*/
static inline int timer_pending(const struct timer_list * timer)
{
- return timer->entry.pprev != NULL;
+ return !hlist_unhashed(&timer->entry);
}
extern void add_timer_on(struct timer_list *timer, int cpu);
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 4820823515e9..9e1c6fc8433a 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -780,6 +780,7 @@ static void do_init_timer(struct timer_list *timer,
const char *name, struct lock_class_key *key)
{
timer->entry.pprev = NULL;
+ timer->expires = 0; /* Avoid bogus 'maybe used uninitialized' warning */
timer->function = func;
timer->flags = flags | raw_smp_processor_id();
lockdep_init_map(&timer->lockdep_map, name, key, 0);
--
2.20.1
next prev parent reply other threads:[~2020-03-24 15:37 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-24 15:36 [RFC PATCH 00/21] Improve list integrity checking Will Deacon
2020-03-24 15:36 ` [RFC PATCH 01/21] list: Remove hlist_unhashed_lockless() Will Deacon
2020-03-24 16:27 ` Greg KH
2020-03-30 23:05 ` Paul E. McKenney
2020-03-24 15:36 ` [RFC PATCH 02/21] list: Remove hlist_nulls_unhashed_lockless() Will Deacon
2020-03-24 16:27 ` Greg KH
2020-03-30 23:07 ` Paul E. McKenney
2020-03-24 15:36 ` [RFC PATCH 03/21] list: Annotate lockless list primitives with data_race() Will Deacon
2020-03-24 16:20 ` Jann Horn
2020-03-24 16:26 ` Greg KH
2020-03-24 16:38 ` Jann Horn
2020-03-24 16:59 ` Greg KH
2020-03-24 18:22 ` Jann Horn
2020-03-24 16:23 ` Marco Elver
2020-03-24 21:33 ` Will Deacon
2020-03-31 13:10 ` Will Deacon
2020-04-01 6:34 ` Marco Elver
2020-04-01 8:40 ` Will Deacon
2020-05-08 13:46 ` [tip: locking/kcsan] kcsan: Change data_race() to no longer require marking racing accesses tip-bot2 for Marco Elver
2020-03-24 16:51 ` [RFC PATCH 03/21] list: Annotate lockless list primitives with data_race() Peter Zijlstra
2020-03-24 16:56 ` Jann Horn
2020-03-24 21:32 ` Will Deacon
2020-03-30 23:13 ` Paul E. McKenney
2020-04-24 17:39 ` Will Deacon
2020-04-27 19:24 ` Paul E. McKenney
2020-03-24 15:36 ` Will Deacon [this message]
2020-03-24 16:30 ` [RFC PATCH 04/21] timers: Use hlist_unhashed() instead of open-coding in timer_pending() Greg KH
2020-03-24 15:36 ` [RFC PATCH 05/21] list: Comment missing WRITE_ONCE() in __list_del() Will Deacon
2020-03-30 23:14 ` Paul E. McKenney
2020-03-24 15:36 ` [RFC PATCH 06/21] list: Remove superfluous WRITE_ONCE() from hlist_nulls implementation Will Deacon
2020-03-30 23:21 ` Paul E. McKenney
2020-03-24 15:36 ` [RFC PATCH 07/21] Revert "list: Use WRITE_ONCE() when adding to lists and hlists" Will Deacon
2020-03-30 23:19 ` Paul E. McKenney
2020-03-24 15:36 ` [RFC PATCH 08/21] Revert "list: Use WRITE_ONCE() when initializing list_head structures" Will Deacon
2020-03-30 23:25 ` Paul E. McKenney
2020-03-31 13:11 ` Will Deacon
2020-03-31 13:47 ` Paul E. McKenney
2020-03-24 15:36 ` [RFC PATCH 09/21] list: Remove unnecessary WRITE_ONCE() from hlist_bl_add_before() Will Deacon
2020-03-30 23:30 ` Paul E. McKenney
2020-03-31 12:37 ` Will Deacon
2020-03-24 15:36 ` [RFC PATCH 10/21] kernel-hacking: Make DEBUG_{LIST,PLIST,SG,NOTIFIERS} non-debug options Will Deacon
2020-03-24 16:42 ` Greg KH
2020-03-24 15:36 ` [RFC PATCH 11/21] list: Add integrity checking to hlist implementation Will Deacon
2020-03-24 15:36 ` [RFC PATCH 12/21] list: Poison ->next pointer for non-RCU deletion of 'hlist_nulls_node' Will Deacon
2020-03-30 23:32 ` Paul E. McKenney
2020-03-24 15:36 ` [RFC PATCH 13/21] list: Add integrity checking to hlist_nulls implementation Will Deacon
2020-03-24 15:36 ` [RFC PATCH 14/21] plist: Use CHECK_DATA_CORRUPTION instead of explicit {BUG,WARN}_ON() Will Deacon
2020-03-24 16:42 ` Greg KH
2020-03-24 15:36 ` [RFC PATCH 15/21] list_bl: Use CHECK_DATA_CORRUPTION instead of custom BUG_ON() wrapper Will Deacon
2020-03-24 15:36 ` [RFC PATCH 16/21] list_bl: Extend integrity checking in deletion routines Will Deacon
2020-03-24 15:36 ` [RFC PATCH 17/21] linux/bit_spinlock.h: Include linux/processor.h Will Deacon
2020-03-24 16:28 ` Greg KH
2020-03-24 21:08 ` Will Deacon
2020-03-24 15:36 ` [RFC PATCH 18/21] list_bl: Move integrity checking out of line Will Deacon
2020-03-24 15:36 ` [RFC PATCH 19/21] list_bl: Extend integrity checking to cover the same cases as 'hlist' Will Deacon
2020-03-24 15:36 ` [RFC PATCH 20/21] list: Format CHECK_DATA_CORRUPTION error messages consistently Will Deacon
2020-03-24 16:40 ` Greg KH
2020-03-24 15:36 ` [RFC PATCH 21/21] lkdtm: Extend list corruption checks Will Deacon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200324153643.15527-5-will@kernel.org \
--to=will@kernel.org \
--cc=edumazet@google.com \
--cc=elver@google.com \
--cc=jannh@google.com \
--cc=keescook@chromium.org \
--cc=kernel-hardening@lists.openwall.com \
--cc=kernel-team@android.com \
--cc=linux-kernel@vger.kernel.org \
--cc=maddiestone@google.com \
--cc=paulmck@kernel.org \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.