From: Kees Cook <keescook@chromium.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: linux-kernel@vger.kernel.org,
Christoph Hellwig <hch@infradead.org>,
Peter Zijlstra <peterz@infradead.org>,
"Eric W. Biederman" <ebiederm@xmission.com>,
Andrew Morton <akpm@linux-foundation.org>,
Josh Poimboeuf <jpoimboe@redhat.com>,
Jann Horn <jannh@google.com>, Eric Biggers <ebiggers3@gmail.com>,
Elena Reshetova <elena.reshetova@intel.com>,
Hans Liljestrand <ishkamiel@gmail.com>,
David Windsor <dwindsor@gmail.com>,
Greg KH <gregkh@linuxfoundation.org>,
Ingo Molnar <mingo@redhat.com>,
Alexey Dobriyan <adobriyan@gmail.com>,
"Serge E. Hallyn" <serge@hallyn.com>,
arozansk@redhat.com, Davidlohr Bueso <dave@stgolabs.net>,
Manfred Spraul <manfred@colorfullife.com>,
"axboe@kernel.dk" <axboe@kernel.dk>,
James Bottomley <James.Bottomley@hansenpartner>
Subject: [PATCH v3] refcount: Create unchecked atomic_t implementation
Date: Wed, 21 Jun 2017 13:00:26 -0700 [thread overview]
Message-ID: <20170621200026.GA115679@beast> (raw)
Many subsystems will not use refcount_t unless there is a way to build the
kernel so that there is no regression in speed compared to atomic_t. This
adds CONFIG_REFCOUNT_FULL to enable the full refcount_t implementation
which has the validation but is slightly slower. When not enabled,
refcount_t uses the basic unchecked atomic_t routines, which results in
no code changes compared to just using atomic_t directly.
Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
v3: unbreak slightly long lines; Ingo. Add Greg's Ack.
v2: use better atomic ops; Elena and Peter.
---
arch/Kconfig | 9 +++++++++
include/linux/refcount.h | 42 ++++++++++++++++++++++++++++++++++++++++++
lib/refcount.c | 3 +++
3 files changed, 54 insertions(+)
diff --git a/arch/Kconfig b/arch/Kconfig
index 6c00e5b00f8b..fba3bf186728 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -867,4 +867,13 @@ config STRICT_MODULE_RWX
config ARCH_WANT_RELAX_ORDER
bool
+config REFCOUNT_FULL
+ bool "Perform full reference count validation at the expense of speed"
+ help
+ Enabling this switches the refcounting infrastructure from a fast
+ unchecked atomic_t implementation to a fully state checked
+ implementation, which can be slower but provides protections
+ against various use-after-free conditions that can be used in
+ security flaw exploits.
+
source "kernel/gcov/Kconfig"
diff --git a/include/linux/refcount.h b/include/linux/refcount.h
index b34aa649d204..bb71f2871dac 100644
--- a/include/linux/refcount.h
+++ b/include/linux/refcount.h
@@ -41,6 +41,7 @@ static inline unsigned int refcount_read(const refcount_t *r)
return atomic_read(&r->refs);
}
+#ifdef CONFIG_REFCOUNT_FULL
extern __must_check bool refcount_add_not_zero(unsigned int i, refcount_t *r);
extern void refcount_add(unsigned int i, refcount_t *r);
@@ -52,6 +53,47 @@ extern void refcount_sub(unsigned int i, refcount_t *r);
extern __must_check bool refcount_dec_and_test(refcount_t *r);
extern void refcount_dec(refcount_t *r);
+#else
+static inline __must_check bool refcount_add_not_zero(unsigned int i, refcount_t *r)
+{
+ return atomic_add_unless(&r->refs, i, 0);
+}
+
+static inline void refcount_add(unsigned int i, refcount_t *r)
+{
+ atomic_add(i, &r->refs);
+}
+
+static inline __must_check bool refcount_inc_not_zero(refcount_t *r)
+{
+ return atomic_add_unless(&r->refs, 1, 0);
+}
+
+static inline void refcount_inc(refcount_t *r)
+{
+ atomic_inc(&r->refs);
+}
+
+static inline __must_check bool refcount_sub_and_test(unsigned int i, refcount_t *r)
+{
+ return atomic_sub_and_test(i, &r->refs);
+}
+
+static inline void refcount_sub(unsigned int i, refcount_t *r)
+{
+ atomic_sub(i, &r->refs);
+}
+
+static inline __must_check bool refcount_dec_and_test(refcount_t *r)
+{
+ return atomic_dec_and_test(&r->refs);
+}
+
+static inline void refcount_dec(refcount_t *r)
+{
+ atomic_dec(&r->refs);
+}
+#endif /* CONFIG_REFCOUNT_FULL */
extern __must_check bool refcount_dec_if_one(refcount_t *r);
extern __must_check bool refcount_dec_not_one(refcount_t *r);
diff --git a/lib/refcount.c b/lib/refcount.c
index 9f906783987e..5d0582a9480c 100644
--- a/lib/refcount.c
+++ b/lib/refcount.c
@@ -37,6 +37,8 @@
#include <linux/refcount.h>
#include <linux/bug.h>
+#ifdef CONFIG_REFCOUNT_FULL
+
/**
* refcount_add_not_zero - add a value to a refcount unless it is 0
* @i: the value to add to the refcount
@@ -225,6 +227,7 @@ void refcount_dec(refcount_t *r)
WARN_ONCE(refcount_dec_and_test(r), "refcount_t: decrement hit 0; leaking memory.\n");
}
EXPORT_SYMBOL(refcount_dec);
+#endif /* CONFIG_REFCOUNT_FULL */
/**
* refcount_dec_if_one - decrement a refcount if it is 1
--
2.7.4
--
Kees Cook
Pixel Security
WARNING: multiple messages have this Message-ID (diff)
From: Kees Cook <keescook@chromium.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: linux-kernel@vger.kernel.org,
Christoph Hellwig <hch@infradead.org>,
Peter Zijlstra <peterz@infradead.org>,
"Eric W. Biederman" <ebiederm@xmission.com>,
Andrew Morton <akpm@linux-foundation.org>,
Josh Poimboeuf <jpoimboe@redhat.com>,
Jann Horn <jannh@google.com>, Eric Biggers <ebiggers3@gmail.com>,
Elena Reshetova <elena.reshetova@intel.com>,
Hans Liljestrand <ishkamiel@gmail.com>,
David Windsor <dwindsor@gmail.com>,
Greg KH <gregkh@linuxfoundation.org>,
Ingo Molnar <mingo@redhat.com>,
Alexey Dobriyan <adobriyan@gmail.com>,
"Serge E. Hallyn" <serge@hallyn.com>,
arozansk@redhat.com, Davidlohr Bueso <dave@stgolabs.net>,
Manfred Spraul <manfred@colorfullife.com>,
"axboe@kernel.dk" <axboe@kernel.dk>,
James Bottomley <James.Bottomley@hansenpartnership.com>,
"x86@kernel.org" <x86@kernel.org>, Arnd Bergmann <arnd@arndb.de>,
"David S. Miller" <davem@davemloft.net>,
Rik van Riel <riel@redhat.com>,
linux-arch <linux-arch@vger.kernel.org>
Subject: [PATCH v3] refcount: Create unchecked atomic_t implementation
Date: Wed, 21 Jun 2017 13:00:26 -0700 [thread overview]
Message-ID: <20170621200026.GA115679@beast> (raw)
Message-ID: <20170621200026.Up6jWb7Pu2O5fFhm8q0ji_V7H4HJu4Vjc3HAVVPRua0@z> (raw)
Many subsystems will not use refcount_t unless there is a way to build the
kernel so that there is no regression in speed compared to atomic_t. This
adds CONFIG_REFCOUNT_FULL to enable the full refcount_t implementation
which has the validation but is slightly slower. When not enabled,
refcount_t uses the basic unchecked atomic_t routines, which results in
no code changes compared to just using atomic_t directly.
Signed-off-by: Kees Cook <keescook@chromium.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
v3: unbreak slightly long lines; Ingo. Add Greg's Ack.
v2: use better atomic ops; Elena and Peter.
---
arch/Kconfig | 9 +++++++++
include/linux/refcount.h | 42 ++++++++++++++++++++++++++++++++++++++++++
lib/refcount.c | 3 +++
3 files changed, 54 insertions(+)
diff --git a/arch/Kconfig b/arch/Kconfig
index 6c00e5b00f8b..fba3bf186728 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -867,4 +867,13 @@ config STRICT_MODULE_RWX
config ARCH_WANT_RELAX_ORDER
bool
+config REFCOUNT_FULL
+ bool "Perform full reference count validation at the expense of speed"
+ help
+ Enabling this switches the refcounting infrastructure from a fast
+ unchecked atomic_t implementation to a fully state checked
+ implementation, which can be slower but provides protections
+ against various use-after-free conditions that can be used in
+ security flaw exploits.
+
source "kernel/gcov/Kconfig"
diff --git a/include/linux/refcount.h b/include/linux/refcount.h
index b34aa649d204..bb71f2871dac 100644
--- a/include/linux/refcount.h
+++ b/include/linux/refcount.h
@@ -41,6 +41,7 @@ static inline unsigned int refcount_read(const refcount_t *r)
return atomic_read(&r->refs);
}
+#ifdef CONFIG_REFCOUNT_FULL
extern __must_check bool refcount_add_not_zero(unsigned int i, refcount_t *r);
extern void refcount_add(unsigned int i, refcount_t *r);
@@ -52,6 +53,47 @@ extern void refcount_sub(unsigned int i, refcount_t *r);
extern __must_check bool refcount_dec_and_test(refcount_t *r);
extern void refcount_dec(refcount_t *r);
+#else
+static inline __must_check bool refcount_add_not_zero(unsigned int i, refcount_t *r)
+{
+ return atomic_add_unless(&r->refs, i, 0);
+}
+
+static inline void refcount_add(unsigned int i, refcount_t *r)
+{
+ atomic_add(i, &r->refs);
+}
+
+static inline __must_check bool refcount_inc_not_zero(refcount_t *r)
+{
+ return atomic_add_unless(&r->refs, 1, 0);
+}
+
+static inline void refcount_inc(refcount_t *r)
+{
+ atomic_inc(&r->refs);
+}
+
+static inline __must_check bool refcount_sub_and_test(unsigned int i, refcount_t *r)
+{
+ return atomic_sub_and_test(i, &r->refs);
+}
+
+static inline void refcount_sub(unsigned int i, refcount_t *r)
+{
+ atomic_sub(i, &r->refs);
+}
+
+static inline __must_check bool refcount_dec_and_test(refcount_t *r)
+{
+ return atomic_dec_and_test(&r->refs);
+}
+
+static inline void refcount_dec(refcount_t *r)
+{
+ atomic_dec(&r->refs);
+}
+#endif /* CONFIG_REFCOUNT_FULL */
extern __must_check bool refcount_dec_if_one(refcount_t *r);
extern __must_check bool refcount_dec_not_one(refcount_t *r);
diff --git a/lib/refcount.c b/lib/refcount.c
index 9f906783987e..5d0582a9480c 100644
--- a/lib/refcount.c
+++ b/lib/refcount.c
@@ -37,6 +37,8 @@
#include <linux/refcount.h>
#include <linux/bug.h>
+#ifdef CONFIG_REFCOUNT_FULL
+
/**
* refcount_add_not_zero - add a value to a refcount unless it is 0
* @i: the value to add to the refcount
@@ -225,6 +227,7 @@ void refcount_dec(refcount_t *r)
WARN_ONCE(refcount_dec_and_test(r), "refcount_t: decrement hit 0; leaking memory.\n");
}
EXPORT_SYMBOL(refcount_dec);
+#endif /* CONFIG_REFCOUNT_FULL */
/**
* refcount_dec_if_one - decrement a refcount if it is 1
--
2.7.4
--
Kees Cook
Pixel Security
next reply other threads:[~2017-06-21 20:00 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-21 20:00 Kees Cook [this message]
2017-06-21 20:00 ` [PATCH v3] refcount: Create unchecked atomic_t implementation Kees Cook
2017-06-22 11:07 ` [tip:locking/core] locking/refcount: " tip-bot for Kees Cook
2017-06-28 16:58 ` tip-bot for Kees Cook
2017-09-04 12:37 ` Peter Zijlstra
2017-09-04 17:11 ` Kees Cook
2017-09-04 17:11 ` Kees Cook
2017-09-04 19:35 ` Peter Zijlstra
2017-09-04 19:35 ` Peter Zijlstra
2017-09-04 17:34 ` Alexey Dobriyan
2017-09-04 19:36 ` Peter Zijlstra
2017-09-05 18:15 ` Alexey Dobriyan
2017-09-06 8:17 ` Peter Zijlstra
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=20170621200026.GA115679@beast \
--to=keescook@chromium.org \
--cc=James.Bottomley@hansenpartner \
--cc=adobriyan@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=arozansk@redhat.com \
--cc=axboe@kernel.dk \
--cc=dave@stgolabs.net \
--cc=dwindsor@gmail.com \
--cc=ebiederm@xmission.com \
--cc=ebiggers3@gmail.com \
--cc=elena.reshetova@intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=hch@infradead.org \
--cc=ishkamiel@gmail.com \
--cc=jannh@google.com \
--cc=jpoimboe@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=manfred@colorfullife.com \
--cc=mingo@kernel.org \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=serge@hallyn.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.