From: "Paul E. McKenney" <paulmck@kernel.org>
To: stern@rowland.harvard.edu, parri.andrea@gmail.com,
will@kernel.org, peterz@infradead.org, boqun.feng@gmail.com,
npiggin@gmail.com, dhowells@redhat.com, j.alglave@ucl.ac.uk,
luc.maranget@inria.fr, akiyks@gmail.com, dlustig@nvidia.com,
joel@joelfernandes.org
Cc: viro@zeniv.linux.org.uk, linux-kernel@vger.kernel.org,
linux-arch@vger.kernel.org
Subject: Litmus test for question from Al Viro
Date: Wed, 30 Sep 2020 21:51:16 -0700 [thread overview]
Message-ID: <20201001045116.GA5014@paulmck-ThinkPad-P72> (raw)
Hello!
Al Viro posted the following query:
------------------------------------------------------------------------
<viro> fun question regarding barriers, if you have time for that
<viro> V->A = V->B = 1;
<viro>
<viro> CPU1:
<viro> to_free = NULL
<viro> spin_lock(&LOCK)
<viro> if (!smp_load_acquire(&V->B))
<viro> to_free = V
<viro> V->A = 0
<viro> spin_unlock(&LOCK)
<viro> kfree(to_free)
<viro>
<viro> CPU2:
<viro> to_free = V;
<viro> if (READ_ONCE(V->A)) {
<viro> spin_lock(&LOCK)
<viro> if (V->A)
<viro> to_free = NULL
<viro> smp_store_release(&V->B, 0);
<viro> spin_unlock(&LOCK)
<viro> }
<viro> kfree(to_free);
<viro> 1) is it guaranteed that V will be freed exactly once and that
no accesses to *V will happen after freeing it?
<viro> 2) do we need smp_store_release() there? I.e. will anything
break if it's replaced with plain V->B = 0?
------------------------------------------------------------------------
Of course herd7 supports neither structures nor arrays, but I was
crazy enough to try individual variables with made-up address and data
dependencies. This litmus test must also detect use-after-free bugs,
but a simple variable should be able to do that. So here is a
prototype:
------------------------------------------------------------------------
C C-viro-2020.09.29a
{
int a = 1;
int b = 1;
int v = 1;
}
P0(int *a, int *b, int *v, spinlock_t *l)
{
int r0;
int r1;
int r2 = 2;
int r8;
int r9a = 2;
int r9b = 2;
r0 = 0;
spin_lock(l);
r9a = READ_ONCE(*v); // Use after free?
r8 = r9a - r9a; // Restore address dependency
r8 = b + r8;
r1 = smp_load_acquire(r8);
if (r1 == 0)
r0 = 1;
r9b = READ_ONCE(*v); // Use after free?
WRITE_ONCE(*a, r9b - r9b); // Use data dependency
spin_unlock(l);
if (r0) {
r2 = READ_ONCE(*v);
WRITE_ONCE(*v, 0); /* kfree(). */
}
}
P1(int *a, int *b, int *v, spinlock_t *l)
{
int r0;
int r1;
int r1a;
int r2 = 2;
int r8;
int r9a = 2;
int r9b = 2;
int r9c = 2;
r0 = READ_ONCE(*v);
r9a = r0; // Use after free?
r8 = r9a - r9a; // Restore address dependency
r8 = a + r8;
r1 = READ_ONCE(*r8);
if (r1) {
spin_lock(l);
r9b = READ_ONCE(*v); // Use after free?
r8 = r9b - r9b; // Restore address dependency
r8 = a + r8;
r1a = READ_ONCE(*r8);
if (r1a)
r0 = 0;
r9c = READ_ONCE(*v); // Use after free?
smp_store_release(b, r9c - rc9); // Use data dependency
spin_unlock(l);
}
if (r0) {
r2 = READ_ONCE(*v);
WRITE_ONCE(*v, 0); /* kfree(). */
}
}
locations [a;b;v;0:r1;0:r8;1:r1;1:r8]
exists (0:r0=1:r0 \/ (* Both or neither did kfree(). *)
v=1 \/ (* Neither did kfree, redundant check. *)
0:r2=0 \/ 1:r2=0 \/ (* Both did kfree, redundant check. *)
0:r9a=0 \/ 0:r9b=0 \/ 1:r9a=0 \/ (* CPU1 use after free. *)
1:r9b=0 \/ 1:r9c=0) (* CPU2 use after free. *)
------------------------------------------------------------------------
This "exists" clause is satisfied:
------------------------------------------------------------------------
$ herd7 -conf linux-kernel.cfg ~/paper/scalability/LWNLinuxMM/litmus/manual/kernel/C-viro-2020.09.29a.litmus
Test C-viro-2020.09.29a Allowed
States 5
0:r0=0; 0:r1=1; 0:r2=2; 0:r8=b; 0:r9a=0; 0:r9b=0; 1:r0=1; 1:r1=0; 1:r2=1; 1:r8=a; 1:r9a=1; 1:r9b=2; 1:r9c=2; a=0; b=1; v=0;
0:r0=0; 0:r1=1; 0:r2=2; 0:r8=b; 0:r9a=1; 0:r9b=0; 1:r0=1; 1:r1=0; 1:r2=1; 1:r8=a; 1:r9a=1; 1:r9b=2; 1:r9c=2; a=0; b=1; v=0;
0:r0=0; 0:r1=1; 0:r2=2; 0:r8=b; 0:r9a=1; 0:r9b=1; 1:r0=0; 1:r1=1; 1:r2=2; 1:r8=a; 1:r9a=1; 1:r9b=1; 1:r9c=1; a=0; b=1; v=1;
0:r0=0; 0:r1=1; 0:r2=2; 0:r8=b; 0:r9a=1; 0:r9b=1; 1:r0=1; 1:r1=0; 1:r2=1; 1:r8=a; 1:r9a=1; 1:r9b=2; 1:r9c=2; a=0; b=1; v=0;
0:r0=0; 0:r1=1; 0:r2=2; 0:r8=b; 0:r9a=1; 0:r9b=1; 1:r0=1; 1:r1=1; 1:r2=1; 1:r8=a; 1:r9a=1; 1:r9b=1; 1:r9c=1; a=0; b=1; v=0;
Ok
Witnesses
Positive: 3 Negative: 2
Condition exists (0:r0=1:r0 \/ v=1 \/ 0:r2=0 \/ 1:r2=0 \/ 0:r9a=0 \/ 0:r9b=0 \/ 1:r9a=0 \/ 1:r9b=0 \/ 1:r9c=0)
Observation C-viro-2020.09.29a Sometimes 3 2
Time C-viro-2020.09.29a 14.33
Hash=89f74abff4de682ee0bea8ee6dd53134
------------------------------------------------------------------------
So did we end up with herd7 not respecting "fake" dependencies like
those shown above, or have I just messed up the translation from Al's
example to the litmus test? (Given one thing and another over the past
couple of days, my guess would be that I just messed up the translation,
especially given that I don't see a reference to fake dependencies in
the documentation, but I figured that I should ask.)
Thanx, Paul
next reply other threads:[~2020-10-01 4:51 UTC|newest]
Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-01 4:51 Paul E. McKenney [this message]
2020-10-01 16:15 ` Litmus test for question from Al Viro Alan Stern
2020-10-01 16:36 ` Al Viro
2020-10-01 18:39 ` Alan Stern
2020-10-01 19:29 ` Al Viro
2020-10-01 21:30 ` Paul E. McKenney
2020-10-03 2:01 ` Alan Stern
2020-10-03 13:22 ` Alan Stern
2020-10-03 15:16 ` Akira Yokosawa
2020-10-03 17:13 ` Bug in herd7 [Was: Re: Litmus test for question from Al Viro] Alan Stern
2020-10-03 22:50 ` Akira Yokosawa
2020-10-04 1:40 ` [PATCH] tools: memory-model: Document that the LKMM can easily miss control dependencies Alan Stern
2020-10-04 21:07 ` joel
2020-10-04 23:12 ` Paul E. McKenney
2020-10-05 15:15 ` Bug in herd7 [Was: Re: Litmus test for question from Al Viro] Luc Maranget
2020-10-05 15:53 ` Alan Stern
2020-10-05 16:52 ` Paul E. McKenney
2020-10-05 18:19 ` Alan Stern
2020-10-05 19:18 ` Paul E. McKenney
2020-10-05 19:48 ` Alan Stern
2020-10-06 16:39 ` Paul E. McKenney
2020-10-06 17:05 ` Alan Stern
2020-10-07 17:50 ` Paul E. McKenney
2020-10-07 19:40 ` Alan Stern
2020-10-07 22:38 ` Paul E. McKenney
2020-10-08 2:25 ` Alan Stern
2020-10-08 2:50 ` Paul E. McKenney
2020-10-08 14:01 ` Alan Stern
2020-10-08 18:32 ` Paul E. McKenney
2020-10-05 15:54 ` Paul E. McKenney
2020-10-04 23:31 ` Litmus test for question from Al Viro Paul E. McKenney
2020-10-05 2:38 ` Alan Stern
2020-10-05 8:20 ` Will Deacon
2020-10-05 9:12 ` Will Deacon
2020-10-05 14:01 ` Paul E. McKenney
2020-10-05 14:23 ` Alan Stern
2020-10-05 15:13 ` Will Deacon
2020-10-05 15:16 ` Alan Stern
2020-10-05 15:35 ` Peter Zijlstra
2020-10-05 15:49 ` Paul E. McKenney
2020-10-05 14:16 ` Alan Stern
2020-10-05 14:03 ` Paul E. McKenney
2020-10-05 14:24 ` Alan Stern
2020-10-05 14:44 ` joel
2020-10-05 15:55 ` Paul E. McKenney
2020-10-05 8:36 ` David Laight
2020-10-05 13:59 ` Paul E. McKenney
2020-10-03 16:08 ` joel
2020-10-03 16:11 ` joel
2020-10-04 23:13 ` Paul E. McKenney
2020-10-03 2:35 ` Jon Masters
2020-10-04 23:32 ` Paul E. McKenney
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=20201001045116.GA5014@paulmck-ThinkPad-P72 \
--to=paulmck@kernel.org \
--cc=akiyks@gmail.com \
--cc=boqun.feng@gmail.com \
--cc=dhowells@redhat.com \
--cc=dlustig@nvidia.com \
--cc=j.alglave@ucl.ac.uk \
--cc=joel@joelfernandes.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luc.maranget@inria.fr \
--cc=npiggin@gmail.com \
--cc=parri.andrea@gmail.com \
--cc=peterz@infradead.org \
--cc=stern@rowland.harvard.edu \
--cc=viro@zeniv.linux.org.uk \
--cc=will@kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox