|
Message-ID: <CAGXu5j+qm6OR5m6RJS87Ahr5_pEzaJkHGcdWwjkxOMywkB1Ahg@mail.gmail.com> Date: Fri, 24 Feb 2012 12:04:12 -0800 From: Kees Cook <keescook@...omium.org> To: Greg KH <gregkh@...uxfoundation.org> Cc: Vasiliy Kulikov <segoon@...nwall.com>, David Windsor <dwindsor@...il.com>, Roland Dreier <roland@...estorage.com>, Djalal Harouni <tixxdz@...ndz.org>, kernel-hardening@...ts.openwall.com, Ubuntu security discussion <ubuntu-hardened@...ts.ubuntu.com>, linux-kernel@...r.kernel.org, pageexec@...email.hu, spender@...ecurity.net Subject: Re: Re: Add overflow protection to kref On Fri, Feb 24, 2012 at 11:41 AM, Greg KH <gregkh@...uxfoundation.org> wrote: > On Fri, Feb 24, 2012 at 10:58:25PM +0400, Vasiliy Kulikov wrote: >> On Fri, Feb 24, 2012 at 10:37 -0800, Greg KH wrote: >> > On Fri, Feb 24, 2012 at 12:58:35PM -0500, David Windsor wrote: >> > > static inline void kref_get(struct kref *kref) >> > > { >> > > + int rc = 0; >> > > WARN_ON(!atomic_read(&kref->refcount)); >> > > - atomic_inc(&kref->refcount); >> > > + smp_mb__before_atomic_inc(); >> > > + rc = atomic_add_unless(&kref->refcount, 1, INT_MAX); >> > > + smp_mb__after_atomic_inc(); >> > > + BUG_ON(!rc); >> > >> > So you are guaranteeing to crash a machine here if this fails? And you >> > were trying to say this is a "security" based fix? >> > >> > And people wonder why I no longer have any hair... >> >> If a refcounter overflows there is NO WAY to recover. The choise is to BUG() >> and not allow any security harm to the system (privilege escalation, etc.) >> or to try to do some more CPU cycles until actual use after free, privilege >> escalation, etc. The former is a _guarantee_ that nothing bad (in security >> sense) doesn't happen. The latter is an opportunistic approach, which >> doesn't work with security. > > The only way you could legimitaly get a real use-after-free problem if > you were overflowing the reference counter and pegged it at the max > value, was if you had code that could decrement the reference count as > many times as you incremented it. So far, all bugs we've seen are > one-off where on an error path, we forgot to decrement the count. So > how could the decrement ever happen? Based on what I've seen, the "normal" exploit follows this pattern: user1: alloc(), inc user2: inc user2: fail to dec *repeat user2's actions until wrap* user3: inc user3: dec, free() user1: operate on freed memory zomg We could avoid the BUG by locking the counter to INT_MAX if it ever reaches it (i.e. the put path would need to be modified too), and then a WARN could be added to the get. Is that what was being suggested as the alternative to the BUG patch? >> Do you claim that a refcounter overflow is a recoverable state? I'd want to >> know what you can do with it. > > I'm not saying it is a "recoverable" state, but to crash the machine is > not acceptable. At the very least, let the user know something went > wrong, and stick around long enough to let them know and do something, > before shutting the thing down. > > But before people start micro-engineering this whole thing, remember, > I'm still not sold on this type of change at all. > > greg k-h > > p.s. Has anyone ever tried an endless open() loop on a sysfs file to see > what happens today?... AIUI, you'd hit nrfile well before wrapping the counter. To test this, we'd need to simulate a failed decrement. -Kees -- Kees Cook ChromeOS Security
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.