linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: "Luruo, Kuthonuzo" <kuthonuzo.luruo@hpe.com>
To: Dmitry Vyukov <dvyukov@google.com>
Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>,
	Alexander Potapenko <glider@google.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	kasan-dev <kasan-dev@googlegroups.com>,
	"linux-mm@kvack.org" <linux-mm@kvack.org>,
	LKML <linux-kernel@vger.kernel.org>
Subject: RE: [PATCH] kasan: improve double-free detection
Date: Sat, 7 May 2016 10:21:44 +0000	[thread overview]
Message-ID: <20E775CA4D599049A25800DE5799F6DD1F6273B2@G4W3225.americas.hpqcorp.net> (raw)
In-Reply-To: <CACT4Y+b9yo58kgkQR5JD+k5N-LNmEF-rPP8OGzoiKkzYUho6FQ@mail.gmail.com>

> >> We can use per-header lock by setting status to KASAN_STATE_LOCKED.  A
> >> thread can CAS any status to KASAN_STATE_LOCKED which means that it
> >> locked the header. If any thread tried to modify/read the status and
> >> the status is KASAN_STATE_LOCKED, then the thread waits.
> >
> > Thanks, Dmitry. I've successfully tested with the concurrent free slab_test test
> > (alloc on cpu 0; then concurrent frees on all other cpus on a 12-vcpu KVM)
> using:
> >
> > static inline bool kasan_alloc_state_lock(struct kasan_alloc_meta *alloc_info)
> > {
> >         if (cmpxchg(&alloc_info->state, KASAN_STATE_ALLOC,
> >                                 KASAN_STATE_LOCKED) == KASAN_STATE_ALLOC)
> >                 return true;
> >         return false;
> > }
> >
> > static inline void kasan_alloc_state_unlock_wait(struct kasan_alloc_meta
> >                 *alloc_info)
> > {
> >         while (alloc_info->state == KASAN_STATE_LOCKED)
> >                 cpu_relax();
> > }
> >
> > Race "winner" sets state to quarantine as the last step:
> >
> >         if (kasan_alloc_state_lock(alloc_info)) {
> >                 free_info = get_free_info(cache, object);
> >                 quarantine_put(free_info, cache);
> >                 set_track(&free_info->track, GFP_NOWAIT);
> >                 kasan_poison_slab_free(cache, object);
> >                 alloc_info->state = KASAN_STATE_QUARANTINE;
> >                 return true;
> >         } else
> >                 kasan_alloc_state_unlock_wait(alloc_info);
> >
> > Now, I'm not sure whether on current KASAN-supported archs, state byte load
> in
> > the busy-wait loop is atomic wrt the KASAN_STATE_QUARANTINE byte store.
> > Would you advise using CAS primitives for load/store here too?
> 
> Store to state needs to use smp_store_release function, otherwise
> stores to free_info->track can sink below the store to state.
> Similarly, loads of state in kasan_alloc_state_unlock_wait need to use
> smp_store_acquire.
> 
> A function similar to kasan_alloc_state_lock will also be needed for
> KASAN_STATE_QUARANTINE -> KASAN_STATE_ALLOC state transition (when we
> reuse the object). If a thread tried to report use-after-free when
> another thread pushes the object out of quarantine and overwrites
> alloc_info->track, the thread will print a bogus stack.
> 
> kasan_alloc_state_unlock_wait is not enough to prevent the races.
> Consider that a thread executes kasan_alloc_state_unlock_wait and
> proceeds to reporting, at this point another thread pushes the object
> to quarantine or out of the quarantine and overwrites tracks. The
> first thread will read inconsistent data from the header. Any thread
> that reads/writes header needs to (1) wait while status is
> KASAN_STATE_LOCKED, (2) CAS status to KASAN_STATE_LOCKED, (3)
> read/write header, (4) restore/update status and effectively unlock
> the header.
> Alternatively, we can introduce LOCKED bit to header. Then it will be
> simpler for readers to set/unset the bit.

Thanks. As implemented in v2, all accesses to object alloc metadata (alloc,
dealloc, bug report and quarantine release) are now performed under
protection of a lock bit. Your suggested cmpxchg() loop for the lock is
paired with an xchg() on unlock which should address the memory ordering
issue.

In your race scenario between UAF and object reuse from new alloc, if
kmalloc wins, "UAF" report  would be bad (probably bug type
"unknown-crash" with thread stack + alloc stack). To close this window,
object meta lock would need to acquired much closer to point of bad
access detection. Patch does not address this race. How does ASAN
address this?

Kuthonuzo

  reply	other threads:[~2016-05-07 10:22 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-02  9:49 Kuthonuzo Luruo
2016-05-02 10:09 ` Dmitry Vyukov
2016-05-02 11:30   ` Luruo, Kuthonuzo
2016-05-02 11:35     ` Dmitry Vyukov
2016-05-03  9:24       ` Luruo, Kuthonuzo
2016-05-03 17:50         ` Dmitry Vyukov
2016-05-07 10:21           ` Luruo, Kuthonuzo [this message]
2016-05-02 11:41   ` Dmitry Vyukov
2016-05-02 11:47     ` Alexander Potapenko
2016-05-03  7:58       ` Luruo, Kuthonuzo
2016-05-03  7:53     ` Luruo, Kuthonuzo
2016-05-03 17:42       ` Dmitry Vyukov
2016-05-04 20:13         ` Luruo, Kuthonuzo
2016-05-05  5:34           ` Dmitry Vyukov
2016-05-05  6:23             ` Luruo, Kuthonuzo
2016-05-05  6:55               ` Dmitry Vyukov
2016-05-07  8:56                 ` Luruo, Kuthonuzo

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=20E775CA4D599049A25800DE5799F6DD1F6273B2@G4W3225.americas.hpqcorp.net \
    --to=kuthonuzo.luruo@hpe.com \
    --cc=akpm@linux-foundation.org \
    --cc=aryabinin@virtuozzo.com \
    --cc=dvyukov@google.com \
    --cc=glider@google.com \
    --cc=kasan-dev@googlegroups.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.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