Commit a2e0602c authored by Elena Reshetova's avatar Elena Reshetova Committed by Linus Torvalds

ipc: convert ipc_namespace.count from atomic_t to refcount_t

refcount_t type and corresponding API should be used instead of atomic_t
when the variable is used as a reference counter.  This allows to avoid
accidental refcounter overflows that might lead to use-after-free
situations.

Link: http://lkml.kernel.org/r/1499417992-3238-2-git-send-email-elena.reshetova@intel.comSigned-off-by: default avatarElena Reshetova <elena.reshetova@intel.com>
Signed-off-by: default avatarHans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarDavid Windsor <dwindsor@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Serge Hallyn <serge@hallyn.com>
Cc: <arozansk@redhat.com>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Manfred Spraul <manfred@colorfullife.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 7483e5d4
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/nsproxy.h> #include <linux/nsproxy.h>
#include <linux/ns_common.h> #include <linux/ns_common.h>
#include <linux/refcount.h>
struct user_namespace; struct user_namespace;
...@@ -19,7 +20,7 @@ struct ipc_ids { ...@@ -19,7 +20,7 @@ struct ipc_ids {
}; };
struct ipc_namespace { struct ipc_namespace {
atomic_t count; refcount_t count;
struct ipc_ids ids[3]; struct ipc_ids ids[3];
int sem_ctls[4]; int sem_ctls[4];
...@@ -118,7 +119,7 @@ extern struct ipc_namespace *copy_ipcs(unsigned long flags, ...@@ -118,7 +119,7 @@ extern struct ipc_namespace *copy_ipcs(unsigned long flags,
static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns) static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns)
{ {
if (ns) if (ns)
atomic_inc(&ns->count); refcount_inc(&ns->count);
return ns; return ns;
} }
......
...@@ -29,7 +29,7 @@ DEFINE_SPINLOCK(mq_lock); ...@@ -29,7 +29,7 @@ DEFINE_SPINLOCK(mq_lock);
* and not CONFIG_IPC_NS. * and not CONFIG_IPC_NS.
*/ */
struct ipc_namespace init_ipc_ns = { struct ipc_namespace init_ipc_ns = {
.count = ATOMIC_INIT(1), .count = REFCOUNT_INIT(1),
.user_ns = &init_user_ns, .user_ns = &init_user_ns,
.ns.inum = PROC_IPC_INIT_INO, .ns.inum = PROC_IPC_INIT_INO,
#ifdef CONFIG_IPC_NS #ifdef CONFIG_IPC_NS
......
...@@ -50,7 +50,7 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns, ...@@ -50,7 +50,7 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns,
goto fail_free; goto fail_free;
ns->ns.ops = &ipcns_operations; ns->ns.ops = &ipcns_operations;
atomic_set(&ns->count, 1); refcount_set(&ns->count, 1);
ns->user_ns = get_user_ns(user_ns); ns->user_ns = get_user_ns(user_ns);
ns->ucounts = ucounts; ns->ucounts = ucounts;
...@@ -144,7 +144,7 @@ static void free_ipc_ns(struct ipc_namespace *ns) ...@@ -144,7 +144,7 @@ static void free_ipc_ns(struct ipc_namespace *ns)
*/ */
void put_ipc_ns(struct ipc_namespace *ns) void put_ipc_ns(struct ipc_namespace *ns)
{ {
if (atomic_dec_and_lock(&ns->count, &mq_lock)) { if (refcount_dec_and_lock(&ns->count, &mq_lock)) {
mq_clear_sbinfo(ns); mq_clear_sbinfo(ns);
spin_unlock(&mq_lock); spin_unlock(&mq_lock);
mq_put_mnt(ns); mq_put_mnt(ns);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment