All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Biggers <ebiggers3@gmail.com>
To: "Reshetova, Elena" <elena.reshetova@intel.com>
Cc: "kernel-hardening@lists.openwall.com"
	<kernel-hardening@lists.openwall.com>,
	"keescook@chromium.org" <keescook@chromium.org>,
	"arnd@arndb.de" <arnd@arndb.de>,
	"tglx@linutronix.de" <tglx@linutronix.de>,
	"mingo@redhat.com" <mingo@redhat.com>,
	"Anvin, H Peter" <h.peter.anvin@intel.com>,
	"peterz@infradead.org" <peterz@infradead.org>,
	"will.deacon@arm.com" <will.deacon@arm.com>,
	"dwindsor@gmail.com" <dwindsor@gmail.com>,
	"gregkh@linuxfoundation.org" <gregkh@linuxfoundation.org>,
	"ishkamiel@gmail.com" <ishkamiel@gmail.com>
Subject: Re: [kernel-hardening] [RFC PATCH 06/19] Provide refcount_t, an atomic_t like primitive built just for refcounting.
Date: Fri, 30 Dec 2016 13:52:13 -0600	[thread overview]
Message-ID: <20161230195213.GA9633@zzz> (raw)
In-Reply-To: <2236FBA76BA1254E88B949DDB74E612B41C32F34@IRSMSX102.ger.corp.intel.com>

On Fri, Dec 30, 2016 at 01:17:08PM +0000, Reshetova, Elena wrote:
> > 
> > ... and refcount_inc() compiles to over 100 bytes of instructions on x86_64.
> > This is the wrong approach.  We need a low-overhead solution, otherwise no one
> > will turn on refcount protection and the feature will be useless.
> > 
> > What exactly is wrong with the current solution in PAX/grsecurity?  Looking at
> > the x86 version they have atomic_inc() do 'lock incl' like usual, then use 'jo'
> > to, if the counter overflowed, jump to *out-of-line* error handling code, in a
> > separate section of the kernel image.   Then it raises a software interrupt, and
> > the interrupt handler sets the overflowed counter to INT_MAX and does the
> > needed
> > logging and signal raising.
> > 
> > That approach seems very efficient.  It seems the only overhead when someone
> > isn't actually exploiting a refcount bug is the 'jo' instruction, with the
> > branch not taken.  There aren't even any other in-line instructions to waste
> > icache space.
> > I do see they used to use a slightly different approach that did a decrement
> > instead of setting the counter to INT_MAX.  And that was clearly racy because
> > two concurrent increments could circumvent the overflow protection.  But AFAICS
> > their current solution is not racy in any meaningful way, since the setting to
> > INT_MAX means an overflow will be detected again on the next increment, even if
> > there were some concurrent increments in the mean time.  (And if by some stretch
> > of the imagination, it was possible to execute *another* INT_MAX increments
> > before the fixup code had a chance to run, the correct solution would be to
> > simply use 'js' instead of 'jo' to detect overflows.  I'm guessing the only
> > reason they don't do that is because some atomic_t's are used to store negative
> > values...)
> 
> > 
> > So given that there is an existing solution which AFAICS is efficient and
> > achieves the desired protection, why has the proposal turned into a monstrous
> > cmpxchg loop that won't be practical to enable by default?
> 
> I guess we can try to benchmark the whole thing to see what is the overhead.
> Especially now when we have the subsystem parts ready. 
> 
> And if you have been following the story since beginning, we also have PaX/grsecurity
> approach done for linux-next/stable and benchmarks have been previously posted, so
> would be easy to compare if needed. 
> 
> I guess one could in principle think of mixed approach between this one and the one that 
> PaX/grsecurity had: define refcount_t type and API, but use assembly instructions
> behind to speed things up. 

I haven't been following the whole story, sorry.  Are your "PaX/grsecurity
approach" patches based on their latest version, i.e. without the racy
decrement?  Also, with regards to benchmarks, there really are two things that
are important: the performance impact of actually executing all the cmpxchg loop
stuff instead of a simple 'lock incl', and the icache footprint of all the extra
inlined instructions (or the overhead of a function call if that is "solved" by
making refcount_inc() out of line).  The latter is unlikely to be visible in a
microbenchmark but it's still very important.

AFAICS the whole question of refcount_t/atomic_t vs.
atomic_t/atomic_unchecked_t has nothing to do with the details of how the
checked refcount operations are actually implemented.  These things need to be
considered separately.

> 
> > I also think that the "warn when incrementing a 0 refcount" part of the change
> > shouldn't be there.  It's additional overhead that seems tangential to the main
> > goal of the feature which is to protect against refcount overflows, not to
> > protect against random increments in some object which has *already* been freed
> > and potentially exploited.
> 
> Actually having warn for now was useful debugging feature: we got to found out many places which would not work otherwise. 
> 

The point of the feature is exploit mitigation, not refcount debugging.  The
mitigation needs to be practical to turn on in real production systems.  If we
want to have extra debugging features too, fine but that should be a *debugging*
feature not a security feature, controllable by a separate config option, e.g.
CONFIG_DEBUG_REFCOUNT for debugging vs. CONFIG_HARDENED_REFCOUNT for the actual
mitigation.

- Eric

  reply	other threads:[~2016-12-30 19:52 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-29  6:55 [kernel-hardening] [RFC PATCH 00/19] refcount_t API + usage Elena Reshetova
2016-12-29  6:55 ` [kernel-hardening] [RFC PATCH 01/19] Since we need to change the implementation, stop exposing internals. Provide kref_read() to read the current reference count; typically used for debug messages Elena Reshetova
2016-12-29 16:41   ` [kernel-hardening] " Greg KH
2016-12-29 16:49     ` Reshetova, Elena
2016-12-30  7:58       ` Greg KH
2016-12-30 12:50         ` Reshetova, Elena
2016-12-29  6:55 ` [kernel-hardening] [RFC PATCH 02/19] By general sentiment kref_sub() is a bad interface, make it go away Elena Reshetova
2016-12-29  6:55 ` [kernel-hardening] [RFC PATCH 03/19] For some obscure reason apparmor thinks its needs to locally implement kref primitives that already exist. Stop doing this Elena Reshetova
2016-12-29  6:55 ` [kernel-hardening] [RFC PATCH 04/19] Because home-rolling your own is _awesome_, stop doing it. Provide kref_put_lock(), just like kref_put_mutex() but for a spinlock Elena Reshetova
2016-12-29  6:55 ` [kernel-hardening] [RFC PATCH 05/19] Leak references by unbalanced get, instead of poking at kref implementation details Elena Reshetova
2016-12-29  6:55 ` [kernel-hardening] [RFC PATCH 06/19] Provide refcount_t, an atomic_t like primitive built just for refcounting Elena Reshetova
2016-12-30  1:06   ` Eric Biggers
2016-12-30 13:17     ` Reshetova, Elena
2016-12-30 19:52       ` Eric Biggers [this message]
2017-01-03 13:21     ` Peter Zijlstra
2017-01-04 20:36       ` Eric Biggers
2017-01-05 10:44         ` Peter Zijlstra
2017-01-05 21:21       ` PaX Team
2017-01-20 10:35         ` Greg KH
2017-01-20 13:10         ` Peter Zijlstra
2016-12-29  6:55 ` [kernel-hardening] [RFC PATCH 07/19] mixed: kref fixes Elena Reshetova
2016-12-29  6:56 ` [kernel-hardening] [RFC PATCH 08/19] kernel, mm: convert from atomic_t to refcount_t Elena Reshetova
2017-01-05  2:25   ` AKASHI Takahiro
2017-01-05  9:56     ` Reshetova, Elena
2017-01-05 19:33       ` Kees Cook
2017-01-10 11:57         ` Reshetova, Elena
2017-01-10 20:34           ` Kees Cook
2017-01-11  9:30             ` Reshetova, Elena
2017-01-11 21:42               ` Kees Cook
2017-01-11 22:55                 ` Kees Cook
2017-01-12  2:55                   ` Kees Cook
2017-01-12  8:02                     ` Reshetova, Elena
2017-01-12  5:11                   ` AKASHI Takahiro
2017-01-12  8:18                     ` Reshetova, Elena
2017-01-12  8:57                     ` Peter Zijlstra
2017-01-16 16:16                       ` Reshetova, Elena
2017-01-17 17:15                         ` Kees Cook
2017-01-17 17:44                           ` Reshetova, Elena
2017-01-17 17:50                             ` David Windsor
2017-01-18  8:41                               ` Reshetova, Elena
2017-01-18  9:03                                 ` gregkh
2017-01-18  9:14                                   ` Reshetova, Elena
2017-01-17 18:26                             ` gregkh
2017-01-12  7:57                   ` Reshetova, Elena
2017-01-12  7:54                 ` Reshetova, Elena
2016-12-29  6:56 ` [kernel-hardening] [RFC PATCH 09/19] net: " Elena Reshetova
2016-12-29  6:56 ` [kernel-hardening] [RFC PATCH 10/19] fs: " Elena Reshetova
2016-12-29  6:56 ` [kernel-hardening] [RFC PATCH 11/19] security: " Elena Reshetova
2016-12-29  6:56 ` [kernel-hardening] [RFC PATCH 12/19] sound: " Elena Reshetova
2016-12-29  6:56 ` [kernel-hardening] [RFC PATCH 13/19] ipc: covert " Elena Reshetova
2016-12-29  6:56 ` [kernel-hardening] [RFC PATCH 14/19] tools: convert " Elena Reshetova
2016-12-29  6:56 ` [kernel-hardening] [RFC PATCH 15/19] block: " Elena Reshetova
2016-12-29  6:56 ` [kernel-hardening] [RFC PATCH 16/19] drivers: net " Elena Reshetova
2016-12-29  6:56 ` [kernel-hardening] [RFC PATCH 17/19] drivers: misc " Elena Reshetova
2016-12-29  6:56 ` [kernel-hardening] [RFC PATCH 18/19] drivers: infiniband " Elena Reshetova

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=20161230195213.GA9633@zzz \
    --to=ebiggers3@gmail.com \
    --cc=arnd@arndb.de \
    --cc=dwindsor@gmail.com \
    --cc=elena.reshetova@intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=h.peter.anvin@intel.com \
    --cc=ishkamiel@gmail.com \
    --cc=keescook@chromium.org \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=will.deacon@arm.com \
    /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.