lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Sun, 18 Oct 2020 17:15:53 -0400
From:   Alan Stern <stern@...land.harvard.edu>
To:     Joel Fernandes <joel@...lfernandes.org>
Cc:     Frederic Weisbecker <frederic@...nel.org>,
        LKML <linux-kernel@...r.kernel.org>,
        Ingo Molnar <mingo@...hat.com>,
        Josh Triplett <josh@...htriplett.org>,
        Lai Jiangshan <jiangshanlai@...il.com>,
        Marco Elver <elver@...gle.com>,
        Mathieu Desnoyers <mathieu.desnoyers@...icios.com>,
        "Paul E. McKenney" <paulmck@...nel.org>, rcu <rcu@...r.kernel.org>,
        Steven Rostedt <rostedt@...dmis.org>,
        "Uladzislau Rezki \(Sony\)" <urezki@...il.com>,
        Frederic Weisbecker <fweisbec@...il.com>,
        Neeraj upadhyay <neeraj.iitr10@...il.com>
Subject: Re: [PATCH v7 6/6] rcu/segcblist: Add additional comments to explain
 smp_mb()

On Sun, Oct 18, 2020 at 01:45:31PM -0700, Joel Fernandes wrote:
> Hi,
> Thanks Alan for your replies.

You're welcome.

> > > C rcubarrier+ctrldep
> > >
> > > (*
> > >  * Result: Never
> > >  *
> > >  * This litmus test shows that rcu_barrier (P1) prematurely
> > >  * returning by reading len 0 can cause issues if P0 does
> > >  * NOT have a smb_mb() after WRITE_ONCE(len, 1).
> > >  * mod_data == 2 means module was unloaded (so data is garbage).
> > >  *)
> > >
> > > { int len = 0; int enq = 0; }
> > >
> > > P0(int *len, int *mod_data, int *enq)
> > > {
> > >       int r0;
> > >
> > >       WRITE_ONCE(*len, 1);
> > >       smp_mb();               /* Needed! */
> > >       WRITE_ONCE(*enq, 1);
> > >
> > >       r0 = READ_ONCE(*mod_data);
> > > }
> > >
> > > P1(int *len, int *mod_data, int *enq)
> > > {
> > >       int r0;
> > >       int r1;
> > >
> > >       r1 = READ_ONCE(*enq);
> > >
> > >       // barrier Just for test purpose ("exists" clause) to force the..
> > >       // ..rcu_barrier() to see enq before len
> > >       smp_mb();
> > >       r0 = READ_ONCE(*len);
> > >
> > >       // implicit memory barrier due to conditional */
> > >       if (r0 == 0)
> > >               WRITE_ONCE(*mod_data, 2);
> > > }
> > >
> > > // Did P0 read garbage?
> > > exists (0:r0=2 /\ 1:r0=0 /\ 1:r1=1)
> >
> > Is this exists clause really what you meant?  Not only can it not be
> > satisfied, it couldn't even be satisfied if you left out the 0:r0=2
> > part.  And smp_mb() is stronger than neessary to enforce this.
> 
> This is indeed what I meant.
> 
> Maybe the exists clause can be simplified, but I just wanted to
> enforce that P1 saw P0's write to enq before seeing anything else.
> 
> Per my test, if you remove the smp_mb() in P0, the test will fail.
> 
> What I wanted to show was P0() seeing mod_data == 2 is bad and should
> never happen (as that implies rcu_barrier() saw len == 0 when it
> should not have). Maybe you can point out what is my test missing?

That's a little tricky, since I don't understand what the test is trying 
to say.

For example, you could change the exists clause to omit "/\ 1:r1=1".  
Maybe that's not a meaningful thing to do... but then it could be 
satisfied simply by having P1 run to completion before P0 starts.

Or you could leave the exists clause as it is and remove the smp_mb() 
from P0.  As you said, that version of the test would also fail since P0 
could then reorder its two writes.

> > However, some memory barrier is needed.  If the smp_mb() in P1 were
> > omitted then P1 would be free to reorder its reads, and the exists
> > clause could be satisfied as follows:
> >
> >         P0                      P1
> >         ------------------------------------------
> >                                 Read len = 0
> >         Write len = 1
> >         smp_mb();
> >         Write enq = 1
> >                                 Read enq = 1
> >                                 Write mod_data = 2
> >         Read mod_data = 2
> 
> Right, so I think I got it right then. I want to show that the control
> dependency in P1 provides the needed ordering. The extra smp_mb() I
> added was just so that I could force P1 to see P0's enqueue.

Yes, it's quite correct that because of the control dependency, P1 
cannot write mod_data before it reads the value of len.

Alan Stern

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ