All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Bart Van Assche <bvanassche@acm.org>
Cc: mingo@redhat.com, tj@kernel.org, longman@redhat.com,
	johannes.berg@intel.com, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v6 00/16] locking/lockdep: Add support for dynamic keys
Date: Mon, 14 Jan 2019 13:52:35 +0100	[thread overview]
Message-ID: <20190114125235.GB20726@hirez.programming.kicks-ass.net> (raw)
In-Reply-To: <1547226101.83374.80.camel@acm.org>

On Fri, Jan 11, 2019 at 09:01:41AM -0800, Bart Van Assche wrote:
> On Fri, 2019-01-11 at 17:55 +0100, Peter Zijlstra wrote:
> > On Fri, Jan 11, 2019 at 07:55:03AM -0800, Bart Van Assche wrote:
> > > On Fri, 2019-01-11 at 13:48 +0100, Peter Zijlstra wrote:
> > > > I spotted this new v6 in my inbox and have rebased to it.
> > > 
> > > Thanks!
> > > 
> > > > On Wed, Jan 09, 2019 at 01:01:48PM -0800, Bart Van Assche wrote:
> > > > 
> > > > > The changes compared to v5 are:
> > > > > - Modified zap_class() such that it doesn't try to free a list entry that
> > > > >   is already being freed.
> > > > 
> > > > I however have a question on this; this seems wrong. Once a list entry
> > > > is enqueued it should not be reachable anymore. If we can reach an entry
> > > > after call_rcu() happened, we've got a problem.
> > > 
> > > Apparently I confused you - sorry that I was not more clear. What I meant is
> > > that I changed a single if test into a loop. The graph lock is held while that
> > > loop is being executed so the code below is serialized against the code called
> > > from inside the RCU callback:
> > > 
> > > @@ -4574,8 +4563,9 @@ static void zap_class(struct pending_free *pf, struct lock
> > > _class *class)
> > >                 entry = list_entries + i;
> > >                 if (entry->class != class && entry->links_to != class)
> > >                         continue;
> > > -               if (__test_and_set_bit(i, pf->list_entries_being_freed))
> > > +               if (list_entry_being_freed(i))
> > >                         continue;
> > 
> > Yes, it is the above change that caught my eye.. That checks _both_ your
> > lists. One is your current open one (@pf), but the other could already
> > be pending the call_rcu().
> > 
> > So my question is why do we have to check both ?! How come the old code,
> > that only checked @pf, is wrong?
> > 
> > > +               set_bit(i, pf->list_entries_being_freed);
> > >                 nr_list_entries--;
> > >                 list_del_rcu(&entry->entry);
> > >         }
> 
> The list_del_rcu() call must only happen once. 

Yes; obviously. But if we need to check all @pf's, that means the entry
is still reachable after a single reset_lock()/free_key_range(), which
is a bug.

> I ran into complaints reporting that
> the list_del_rcu() call triggered list corruption. This change made these complaints
> disappear.

I'm saying this solution buggy, because that means the entry is still
reachable after we do call_rcu() (which is a straight up UAF).

Also put it differently, what guarantees checking those two @pf's is
sufficient. Suppose your earlier @pf already did the RCU callback and
freed stuff while the second is in progress. Then you're poking into
dead space.

  reply	other threads:[~2019-01-14 12:52 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-09 21:01 [PATCH v6 00/16] locking/lockdep: Add support for dynamic keys Bart Van Assche
2019-01-09 21:01 ` [PATCH v6 01/16] locking/lockdep: Fix reported required memory size Bart Van Assche
2019-01-09 21:01 ` [PATCH v6 02/16] locking/lockdep: Avoid that add_chain_cache() adds an invalid chain to the cache Bart Van Assche
2019-01-09 21:01 ` [PATCH v6 03/16] locking/lockdep: Make zap_class() remove all matching lock order entries Bart Van Assche
2019-01-09 21:01 ` [PATCH v6 04/16] locking/lockdep: Reorder struct lock_class members Bart Van Assche
2019-01-09 21:01 ` [PATCH v6 05/16] locking/lockdep: Initialize the locks_before and locks_after lists earlier Bart Van Assche
2019-01-09 21:01 ` [PATCH v6 06/16] locking/lockdep: Split lockdep_free_key_range() and lockdep_reset_lock() Bart Van Assche
2019-01-09 21:01 ` [PATCH v6 07/16] locking/lockdep: Make it easy to detect whether or not inside a selftest Bart Van Assche
2019-01-09 21:01 ` [PATCH v6 08/16] locking/lockdep: Free lock classes that are no longer in use Bart Van Assche
2019-01-09 21:01 ` [PATCH v6 09/16] locking/lockdep: Reuse list entries " Bart Van Assche
2019-01-09 21:01 ` [PATCH v6 10/16] locking/lockdep: Introduce lockdep_next_lockchain() and lock_chain_count() Bart Van Assche
2019-01-09 21:01 ` [PATCH v6 11/16] locking/lockdep: Reuse lock chains that have been freed Bart Van Assche
2019-01-09 21:02 ` [PATCH v6 12/16] locking/lockdep: Check data structure consistency Bart Van Assche
2019-01-09 21:02 ` [PATCH v6 13/16] locking/lockdep: Verify whether lock objects are small enough to be used as class keys Bart Van Assche
2019-01-09 21:02 ` [PATCH v6 14/16] locking/lockdep: Add support for dynamic keys Bart Van Assche
2019-01-09 21:02 ` [PATCH v6 15/16] kernel/workqueue: Use dynamic lockdep keys for workqueues Bart Van Assche
2019-01-09 21:02 ` [PATCH v6 16/16] lockdep tests: Test dynamic key registration Bart Van Assche
2019-01-11 12:48 ` [PATCH v6 00/16] locking/lockdep: Add support for dynamic keys Peter Zijlstra
2019-01-11 15:55   ` Bart Van Assche
2019-01-11 16:55     ` Peter Zijlstra
2019-01-11 17:01       ` Bart Van Assche
2019-01-14 12:52         ` Peter Zijlstra [this message]
2019-01-14 16:52           ` Bart Van Assche
2019-01-18  9:48             ` Peter Zijlstra
2019-01-19  2:34               ` Bart Van Assche
2019-02-01 12:15                 ` Peter Zijlstra
2019-02-03 17:36                   ` Bart Van Assche
2019-02-08 11:43                     ` Will Deacon
2019-02-08 16:31                       ` Bart Van Assche
2019-02-13 22:32                       ` Bart Van Assche

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=20190114125235.GB20726@hirez.programming.kicks-ass.net \
    --to=peterz@infradead.org \
    --cc=bvanassche@acm.org \
    --cc=johannes.berg@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=longman@redhat.com \
    --cc=mingo@redhat.com \
    --cc=tj@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 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.