Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1723259 > unrolled thread

[PATCH 00/15] v5 kernel core pieces refcount conversions

Started byElena Reshetova <elena.reshetova@intel.com>
First post2017-08-30 14:30 +0200
Last post2017-09-01 19:10 +0200
Articles 20 on this page of 23 — 5 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 00/15] v5 kernel core pieces refcount conversions Elena Reshetova <elena.reshetova@intel.com> - 2017-08-30 14:30 +0200
    [PATCH 05/15] sched/task_struct: convert task_struct.usage to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-08-30 14:30 +0200
    [PATCH 10/15] uprobes: convert uprobe.ref to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-08-30 14:30 +0200
    [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-08-30 14:30 +0200
      Re: [PATCH 14/15] futex: convert futex_pi_state.refcount to  refcount_t Thomas Gleixner <tglx@linutronix.de> - 2017-09-01 09:50 +0200
        Re: [PATCH 14/15] futex: convert futex_pi_state.refcount to  refcount_t Peter Zijlstra <peterz@infradead.org> - 2017-09-01 11:40 +0200
          Re: [PATCH 14/15] futex: convert futex_pi_state.refcount to  refcount_t Thomas Gleixner <tglx@linutronix.de> - 2017-09-01 11:50 +0200
            RE: [PATCH 14/15] futex: convert futex_pi_state.refcount to  refcount_t "Reshetova, Elena" <elena.reshetova@intel.com> - 2017-09-01 13:00 +0200
            RE: [PATCH 14/15] futex: convert futex_pi_state.refcount to  refcount_t "Reshetova, Elena" <elena.reshetova@intel.com> - 2017-09-01 13:10 +0200
              Re: [PATCH 14/15] futex: convert futex_pi_state.refcount to  refcount_t Peter Zijlstra <peterz@infradead.org> - 2017-09-01 14:40 +0200
                RE: [PATCH 14/15] futex: convert futex_pi_state.refcount to  refcount_t "Reshetova, Elena" <elena.reshetova@intel.com> - 2017-09-01 15:30 +0200
                  Re: [PATCH 14/15] futex: convert futex_pi_state.refcount to  refcount_t Peter Zijlstra <peterz@infradead.org> - 2017-09-01 15:40 +0200
                    RE: [PATCH 14/15] futex: convert futex_pi_state.refcount to  refcount_t "Reshetova, Elena" <elena.reshetova@intel.com> - 2017-09-01 19:10 +0200
                      Re: [PATCH 14/15] futex: convert futex_pi_state.refcount to  refcount_t Peter Zijlstra <peterz@infradead.org> - 2017-09-01 21:20 +0200
                        RE: [PATCH 14/15] futex: convert futex_pi_state.refcount to  refcount_t "Reshetova, Elena" <elena.reshetova@intel.com> - 2017-09-04 12:40 +0200
                          Re: [PATCH 14/15] futex: convert futex_pi_state.refcount to  refcount_t Peter Zijlstra <peterz@infradead.org> - 2017-09-04 14:10 +0200
    [PATCH 07/15] perf: convert perf_event_context.refcount to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-08-30 14:30 +0200
    [PATCH 03/15] sched: convert user_struct.__count to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-08-30 14:30 +0200
    [PATCH 11/15] nsproxy: convert nsproxy.count to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-08-30 14:30 +0200
    Re: [PATCH 00/15] v5 kernel core pieces refcount conversions Kees Cook <keescook@chromium.org> - 2017-09-01 01:50 +0200
      Re: [PATCH 00/15] v5 kernel core pieces refcount conversions Peter Zijlstra <peterz@infradead.org> - 2017-09-01 11:50 +0200
        Re: [PATCH 00/15] v5 kernel core pieces refcount conversions Kees Cook <keescook@chromium.org> - 2017-09-01 19:00 +0200
          RE: [PATCH 00/15] v5 kernel core pieces refcount conversions "Reshetova, Elena" <elena.reshetova@intel.com> - 2017-09-01 19:10 +0200

Page 1 of 2  [1] 2  Next page →


#1723259 — [PATCH 00/15] v5 kernel core pieces refcount conversions

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-08-30 14:30 +0200
Subject[PATCH 00/15] v5 kernel core pieces refcount conversions
Message-ID<ukai5-8hx-3@gated-at.bofh.it>
Now we have at least x86 support for ARCH_HAS_REFCOUNT merged and
arm and others on their way.

Changes in v5:
 * Kees catched that the following changes in
   perf_event_context.refcount and futex_pi_state.refcount
   are not correct now when ARCH_HAS_REFCOUNT is enabled:
    -	WARN_ON(!atomic_inc_not_zero(refcount));
    +	refcount_inc(refcount);
   So they are now changed back to using refcount_inc_not_zero. 

Changes in v4:
 * just rebase and corrections on linux-next/master

Changes in v3:
 * SoB chain corrected
 * minor corrections based on v2 feedback
 * rebase on linux-next/master as of today

Changes in v2:
 * dropped already merged patches
 * rebase on top of linux-next/master
 * Now by default refcount_t = atomic_t (*) and uses all atomic
   standard operations unless CONFIG_REFCOUNT_FULL is enabled.
   This is a compromise for the systems that are critical on
   performance (such as net) and cannot accept even slight delay
   on the refcounter operations.

This series, for core kernel components, replaces atomic_t reference
counters with the new refcount_t type and API (see include/linux/refcount.h).
By doing this we prevent intentional or accidental
underflows or overflows that can led to use-after-free vulnerabilities.

The patches are fully independent and can be cherry-picked separately.
If there are no objections to the patches, please merge them via respective trees.


Elena Reshetova (15):
  sched: convert sighand_struct.count to refcount_t
  sched: convert signal_struct.sigcnt to refcount_t
  sched: convert user_struct.__count to refcount_t
  sched: convert numa_group.refcount to refcount_t
  sched/task_struct: convert task_struct.usage to refcount_t
  sched/task_struct: convert task_struct.stack_refcount to refcount_t
  perf: convert perf_event_context.refcount to refcount_t
  perf/ring_buffer: convert ring_buffer.refcount to refcount_t
  perf/ring_buffer: convert ring_buffer.aux_refcount to refcount_t
  uprobes: convert uprobe.ref to refcount_t
  nsproxy: convert nsproxy.count to refcount_t
  groups: convert group_info.usage to refcount_t
  creds: convert cred.usage to refcount_t
  futex: convert futex_pi_state.refcount to refcount_t
  kcov: convert kcov.refcount to refcount_t

 fs/exec.c                        |  4 ++--
 fs/proc/task_nommu.c             |  2 +-
 include/linux/cred.h             | 13 ++++++------
 include/linux/init_task.h        |  7 +++---
 include/linux/nsproxy.h          |  6 +++---
 include/linux/perf_event.h       |  3 ++-
 include/linux/sched.h            |  5 +++--
 include/linux/sched/signal.h     |  5 +++--
 include/linux/sched/task.h       |  4 ++--
 include/linux/sched/task_stack.h |  2 +-
 include/linux/sched/user.h       |  5 +++--
 kernel/cred.c                    | 46 ++++++++++++++++++++--------------------
 kernel/events/core.c             | 18 ++++++++--------
 kernel/events/internal.h         |  5 +++--
 kernel/events/ring_buffer.c      |  8 +++----
 kernel/events/uprobes.c          |  8 +++----
 kernel/fork.c                    | 24 ++++++++++-----------
 kernel/futex.c                   | 13 ++++++------
 kernel/groups.c                  |  2 +-
 kernel/kcov.c                    |  9 ++++----
 kernel/nsproxy.c                 |  6 +++---
 kernel/sched/fair.c              | 12 +++++------
 kernel/user.c                    |  8 +++----
 23 files changed, 112 insertions(+), 103 deletions(-)

-- 
2.7.4

[toc] | [next] | [standalone]


#1723260 — [PATCH 05/15] sched/task_struct: convert task_struct.usage to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-08-30 14:30 +0200
Subject[PATCH 05/15] sched/task_struct: convert task_struct.usage to refcount_t
Message-ID<ukai6-8hx-39@gated-at.bofh.it>
In reply to#1723259
atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable task_struct.usage is used as pure reference counter.
Convert it to refcount_t and fix up the operations.

Suggested-by: Kees Cook <keescook@chromium.org>
Reviewed-by: David Windsor <dwindsor@gmail.com>
Reviewed-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
---
 include/linux/init_task.h  | 2 +-
 include/linux/sched.h      | 3 ++-
 include/linux/sched/task.h | 4 ++--
 kernel/fork.c              | 4 ++--
 4 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 6c6f520..d312376 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -227,7 +227,7 @@ extern struct cred init_cred;
 	INIT_TASK_TI(tsk)						\
 	.state		= 0,						\
 	.stack		= init_stack,					\
-	.usage		= ATOMIC_INIT(2),				\
+	.usage		= REFCOUNT_INIT(2),				\
 	.flags		= PF_KTHREAD,					\
 	.prio		= MAX_PRIO-20,					\
 	.static_prio	= MAX_PRIO-20,					\
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 6110471..1eeb300 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -20,6 +20,7 @@
 #include <linux/seccomp.h>
 #include <linux/nodemask.h>
 #include <linux/rcupdate.h>
+#include <linux/refcount.h>
 #include <linux/resource.h>
 #include <linux/latencytop.h>
 #include <linux/sched/prio.h>
@@ -534,7 +535,7 @@ struct task_struct {
 	randomized_struct_fields_start
 
 	void				*stack;
-	atomic_t			usage;
+	refcount_t			usage;
 	/* Per task flags (PF_*), defined further below: */
 	unsigned int			flags;
 	unsigned int			ptrace;
diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h
index 79a2a74..2ddc9b0 100644
--- a/include/linux/sched/task.h
+++ b/include/linux/sched/task.h
@@ -85,13 +85,13 @@ extern void sched_exec(void);
 #define sched_exec()   {}
 #endif
 
-#define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0)
+#define get_task_struct(tsk) do { refcount_inc(&(tsk)->usage); } while(0)
 
 extern void __put_task_struct(struct task_struct *t);
 
 static inline void put_task_struct(struct task_struct *t)
 {
-	if (atomic_dec_and_test(&t->usage))
+	if (refcount_dec_and_test(&t->usage))
 		__put_task_struct(t);
 }
 
diff --git a/kernel/fork.c b/kernel/fork.c
index d2e2eb0..1e54683 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -407,7 +407,7 @@ static inline void put_signal_struct(struct signal_struct *sig)
 void __put_task_struct(struct task_struct *tsk)
 {
 	WARN_ON(!tsk->exit_state);
-	WARN_ON(atomic_read(&tsk->usage));
+	WARN_ON(refcount_read(&tsk->usage));
 	WARN_ON(tsk == current);
 
 	cgroup_free(tsk);
@@ -564,7 +564,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node)
 	 * One for us, one for whoever does the "release_task()" (usually
 	 * parent)
 	 */
-	atomic_set(&tsk->usage, 2);
+	refcount_set(&tsk->usage, 2);
 #ifdef CONFIG_BLK_DEV_IO_TRACE
 	tsk->btrace_seq = 0;
 #endif
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1723261 — [PATCH 10/15] uprobes: convert uprobe.ref to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-08-30 14:30 +0200
Subject[PATCH 10/15] uprobes: convert uprobe.ref to refcount_t
Message-ID<ukai7-8hx-43@gated-at.bofh.it>
In reply to#1723259
atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable uprobe.ref is used as pure reference counter.
Convert it to refcount_t and fix up the operations.

Suggested-by: Kees Cook <keescook@chromium.org>
Reviewed-by: David Windsor <dwindsor@gmail.com>
Reviewed-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
---
 kernel/events/uprobes.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 456596d..ca093957 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -66,7 +66,7 @@ static struct percpu_rw_semaphore dup_mmap_sem;
 
 struct uprobe {
 	struct rb_node		rb_node;	/* node in the rb tree */
-	atomic_t		ref;
+	refcount_t		ref;
 	struct rw_semaphore	register_rwsem;
 	struct rw_semaphore	consumer_rwsem;
 	struct list_head	pending_list;
@@ -371,13 +371,13 @@ set_orig_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long v
 
 static struct uprobe *get_uprobe(struct uprobe *uprobe)
 {
-	atomic_inc(&uprobe->ref);
+	refcount_inc(&uprobe->ref);
 	return uprobe;
 }
 
 static void put_uprobe(struct uprobe *uprobe)
 {
-	if (atomic_dec_and_test(&uprobe->ref))
+	if (refcount_dec_and_test(&uprobe->ref))
 		kfree(uprobe);
 }
 
@@ -459,7 +459,7 @@ static struct uprobe *__insert_uprobe(struct uprobe *uprobe)
 	rb_link_node(&uprobe->rb_node, parent, p);
 	rb_insert_color(&uprobe->rb_node, &uprobes_tree);
 	/* get access + creation ref */
-	atomic_set(&uprobe->ref, 2);
+	refcount_set(&uprobe->ref, 2);
 
 	return u;
 }
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1723262 — [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-08-30 14:30 +0200
Subject[PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t
Message-ID<ukai7-8hx-49@gated-at.bofh.it>
In reply to#1723259
atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable futex_pi_state.refcount is used as pure
reference counter. Convert it to refcount_t and fix up
the operations.

Suggested-by: Kees Cook <keescook@chromium.org>
Reviewed-by: David Windsor <dwindsor@gmail.com>
Reviewed-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
---
 kernel/futex.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/kernel/futex.c b/kernel/futex.c
index 0939255..65460b4 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -67,6 +67,7 @@
 #include <linux/freezer.h>
 #include <linux/bootmem.h>
 #include <linux/fault-inject.h>
+#include <linux/refcount.h>
 
 #include <asm/futex.h>
 
@@ -209,7 +210,7 @@ struct futex_pi_state {
 	struct rt_mutex pi_mutex;
 
 	struct task_struct *owner;
-	atomic_t refcount;
+	refcount_t refcount;
 
 	union futex_key key;
 } __randomize_layout;
@@ -795,7 +796,7 @@ static int refill_pi_state_cache(void)
 	INIT_LIST_HEAD(&pi_state->list);
 	/* pi_mutex gets initialized later */
 	pi_state->owner = NULL;
-	atomic_set(&pi_state->refcount, 1);
+	refcount_set(&pi_state->refcount, 1);
 	pi_state->key = FUTEX_KEY_INIT;
 
 	current->pi_state_cache = pi_state;
@@ -815,7 +816,7 @@ static struct futex_pi_state *alloc_pi_state(void)
 
 static void get_pi_state(struct futex_pi_state *pi_state)
 {
-	WARN_ON_ONCE(!atomic_inc_not_zero(&pi_state->refcount));
+	WARN_ON_ONCE(!refcount_inc_not_zero(&pi_state->refcount));
 }
 
 /*
@@ -829,7 +830,7 @@ static void put_pi_state(struct futex_pi_state *pi_state)
 	if (!pi_state)
 		return;
 
-	if (!atomic_dec_and_test(&pi_state->refcount))
+	if (!refcount_dec_and_test(&pi_state->refcount))
 		return;
 
 	/*
@@ -853,7 +854,7 @@ static void put_pi_state(struct futex_pi_state *pi_state)
 		 * refcount is at 0 - put it back to 1.
 		 */
 		pi_state->owner = NULL;
-		atomic_set(&pi_state->refcount, 1);
+		refcount_set(&pi_state->refcount, 1);
 		current->pi_state_cache = pi_state;
 	}
 }
@@ -1051,7 +1052,7 @@ static int attach_to_pi_state(u32 __user *uaddr, u32 uval,
 	 * and futex_wait_requeue_pi() as it cannot go to 0 and consequently
 	 * free pi_state before we can take a reference ourselves.
 	 */
-	WARN_ON(!atomic_read(&pi_state->refcount));
+	WARN_ON(!refcount_read(&pi_state->refcount));
 
 	/*
 	 * Now that we have a pi_state, we can acquire wait_lock
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1724842 — Re: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t

FromThomas Gleixner <tglx@linutronix.de>
Date2017-09-01 09:50 +0200
SubjectRe: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t
Message-ID<ukOSd-Pw-5@gated-at.bofh.it>
In reply to#1723262
On Wed, 30 Aug 2017, Elena Reshetova wrote:
> atomic_t variables are currently used to implement reference
> counters with the following properties:
>  - counter is initialized to 1 using atomic_set()
>  - a resource is freed upon counter reaching zero
>  - once counter reaches zero, its further
>    increments aren't allowed
>  - counter schema uses basic atomic operations
>    (set, inc, inc_not_zero, dec_and_test, etc.)
> 
> Such atomic variables should be converted to a newly provided
> refcount_t type and API that prevents accidental counter overflows
> and underflows. This is important since overflows and underflows
> can lead to use-after-free situation and be exploitable.
> 
> The variable futex_pi_state.refcount is used as pure
> reference counter. Convert it to refcount_t and fix up
> the operations.
> 
> Suggested-by: Kees Cook <keescook@chromium.org>
> Reviewed-by: David Windsor <dwindsor@gmail.com>
> Reviewed-by: Hans Liljestrand <ishkamiel@gmail.com>
> Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

[toc] | [prev] | [next] | [standalone]


#1724913 — Re: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t

FromPeter Zijlstra <peterz@infradead.org>
Date2017-09-01 11:40 +0200
SubjectRe: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t
Message-ID<ukQAG-21R-21@gated-at.bofh.it>
In reply to#1724842
On Fri, Sep 01, 2017 at 09:39:50AM +0200, Thomas Gleixner wrote:
> On Wed, 30 Aug 2017, Elena Reshetova wrote:
> > atomic_t variables are currently used to implement reference
> > counters with the following properties:
> >  - counter is initialized to 1 using atomic_set()
> >  - a resource is freed upon counter reaching zero
> >  - once counter reaches zero, its further
> >    increments aren't allowed
> >  - counter schema uses basic atomic operations
> >    (set, inc, inc_not_zero, dec_and_test, etc.)
> > 
> > Such atomic variables should be converted to a newly provided
> > refcount_t type and API that prevents accidental counter overflows
> > and underflows. This is important since overflows and underflows
> > can lead to use-after-free situation and be exploitable.
> > 
> > The variable futex_pi_state.refcount is used as pure
> > reference counter. Convert it to refcount_t and fix up
> > the operations.
> > 
> > Suggested-by: Kees Cook <keescook@chromium.org>
> > Reviewed-by: David Windsor <dwindsor@gmail.com>
> > Reviewed-by: Hans Liljestrand <ishkamiel@gmail.com>
> > Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
> 
> Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

So the thing to be careful with for things like futex and some of the
other core kernel code is the memory ordering.

atomic_dec_and_test() provides a full smp_mb() before and after,
refcount_dec_and_test() only provides release semantics.

This is typically sufficient, and I would argue that if we rely on more
than that, there _should_ be a comment, however reality isn't always as
nice.

That said, I think this conversion is OK, pi_state->refcount isn't
relied upon to provide additional memory ordering above and beyond what
refcounting requires.

[toc] | [prev] | [next] | [standalone]


#1724917 — Re: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t

FromThomas Gleixner <tglx@linutronix.de>
Date2017-09-01 11:50 +0200
SubjectRe: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t
Message-ID<ukQKl-25K-1@gated-at.bofh.it>
In reply to#1724913
On Fri, 1 Sep 2017, Peter Zijlstra wrote:
> On Fri, Sep 01, 2017 at 09:39:50AM +0200, Thomas Gleixner wrote:
> > On Wed, 30 Aug 2017, Elena Reshetova wrote:
> > > atomic_t variables are currently used to implement reference
> > > counters with the following properties:
> > >  - counter is initialized to 1 using atomic_set()
> > >  - a resource is freed upon counter reaching zero
> > >  - once counter reaches zero, its further
> > >    increments aren't allowed
> > >  - counter schema uses basic atomic operations
> > >    (set, inc, inc_not_zero, dec_and_test, etc.)
> > > 
> > > Such atomic variables should be converted to a newly provided
> > > refcount_t type and API that prevents accidental counter overflows
> > > and underflows. This is important since overflows and underflows
> > > can lead to use-after-free situation and be exploitable.
> > > 
> > > The variable futex_pi_state.refcount is used as pure
> > > reference counter. Convert it to refcount_t and fix up
> > > the operations.
> > > 
> > > Suggested-by: Kees Cook <keescook@chromium.org>
> > > Reviewed-by: David Windsor <dwindsor@gmail.com>
> > > Reviewed-by: Hans Liljestrand <ishkamiel@gmail.com>
> > > Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
> > 
> > Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
> 
> So the thing to be careful with for things like futex and some of the
> other core kernel code is the memory ordering.
> 
> atomic_dec_and_test() provides a full smp_mb() before and after,
> refcount_dec_and_test() only provides release semantics.
> 
> This is typically sufficient, and I would argue that if we rely on more
> than that, there _should_ be a comment, however reality isn't always as
> nice.
> 
> That said, I think this conversion is OK, pi_state->refcount isn't
> relied upon to provide additional memory ordering above and beyond what
> refcounting requires.

So the changelogs should reflect that. The current one suggests that this
is a one to one replacement for atomic_t just with the extra sanity checks
added.

Thanks,

	tglx

[toc] | [prev] | [next] | [standalone]


#1724966 — RE: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t

From"Reshetova, Elena" <elena.reshetova@intel.com>
Date2017-09-01 13:00 +0200
SubjectRE: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t
Message-ID<ukRQ6-2Wd-9@gated-at.bofh.it>
In reply to#1724917
> On Fri, 1 Sep 2017, Peter Zijlstra wrote:
> > On Fri, Sep 01, 2017 at 09:39:50AM +0200, Thomas Gleixner wrote:
> > > On Wed, 30 Aug 2017, Elena Reshetova wrote:
> > > > atomic_t variables are currently used to implement reference
> > > > counters with the following properties:
> > > >  - counter is initialized to 1 using atomic_set()
> > > >  - a resource is freed upon counter reaching zero
> > > >  - once counter reaches zero, its further
> > > >    increments aren't allowed
> > > >  - counter schema uses basic atomic operations
> > > >    (set, inc, inc_not_zero, dec_and_test, etc.)
> > > >
> > > > Such atomic variables should be converted to a newly provided
> > > > refcount_t type and API that prevents accidental counter overflows
> > > > and underflows. This is important since overflows and underflows
> > > > can lead to use-after-free situation and be exploitable.
> > > >
> > > > The variable futex_pi_state.refcount is used as pure
> > > > reference counter. Convert it to refcount_t and fix up
> > > > the operations.
> > > >
> > > > Suggested-by: Kees Cook <keescook@chromium.org>
> > > > Reviewed-by: David Windsor <dwindsor@gmail.com>
> > > > Reviewed-by: Hans Liljestrand <ishkamiel@gmail.com>
> > > > Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
> > >
> > > Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
> >
> > So the thing to be careful with for things like futex and some of the
> > other core kernel code is the memory ordering.
> >
> > atomic_dec_and_test() provides a full smp_mb() before and after,
> > refcount_dec_and_test() only provides release semantics.
> >
> > This is typically sufficient, and I would argue that if we rely on more
> > than that, there _should_ be a comment, however reality isn't always as
> > nice.
> >
> > That said, I think this conversion is OK, pi_state->refcount isn't
> > relied upon to provide additional memory ordering above and beyond what
> > refcounting requires.
> 
> So the changelogs should reflect that. The current one suggests that this
> is a one to one replacement for atomic_t just with the extra sanity checks
> added.

I will update the commit texts accordingly and resend the whole series since
this should be then mentioned in every commit to make sure it is not missed.

Best Regards,
Elena.

> 
> Thanks,
> 
> 	tglx

[toc] | [prev] | [next] | [standalone]


#1724971 — RE: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t

From"Reshetova, Elena" <elena.reshetova@intel.com>
Date2017-09-01 13:10 +0200
SubjectRE: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t
Message-ID<ukRZL-3id-7@gated-at.bofh.it>
In reply to#1724917
 > On Fri, 1 Sep 2017, Peter Zijlstra wrote:
> > > On Fri, Sep 01, 2017 at 09:39:50AM +0200, Thomas Gleixner wrote:
> > > > On Wed, 30 Aug 2017, Elena Reshetova wrote:
> > > > > atomic_t variables are currently used to implement reference
> > > > > counters with the following properties:
> > > > >  - counter is initialized to 1 using atomic_set()
> > > > >  - a resource is freed upon counter reaching zero
> > > > >  - once counter reaches zero, its further
> > > > >    increments aren't allowed
> > > > >  - counter schema uses basic atomic operations
> > > > >    (set, inc, inc_not_zero, dec_and_test, etc.)
> > > > >
> > > > > Such atomic variables should be converted to a newly provided
> > > > > refcount_t type and API that prevents accidental counter overflows
> > > > > and underflows. This is important since overflows and underflows
> > > > > can lead to use-after-free situation and be exploitable.
> > > > >
> > > > > The variable futex_pi_state.refcount is used as pure
> > > > > reference counter. Convert it to refcount_t and fix up
> > > > > the operations.
> > > > >
> > > > > Suggested-by: Kees Cook <keescook@chromium.org>
> > > > > Reviewed-by: David Windsor <dwindsor@gmail.com>
> > > > > Reviewed-by: Hans Liljestrand <ishkamiel@gmail.com>
> > > > > Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
> > > >
> > > > Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
> > >
> > > So the thing to be careful with for things like futex and some of the
> > > other core kernel code is the memory ordering.
> > >
> > > atomic_dec_and_test() provides a full smp_mb() before and after,
> > > refcount_dec_and_test() only provides release semantics.
> > >
> > > This is typically sufficient, and I would argue that if we rely on more
> > > than that, there _should_ be a comment, however reality isn't always as
> > > nice.
> > >
> > > That said, I think this conversion is OK, pi_state->refcount isn't
> > > relied upon to provide additional memory ordering above and beyond what
> > > refcounting requires.
> >
> > So the changelogs should reflect that. The current one suggests that this
> > is a one to one replacement for atomic_t just with the extra sanity checks
> > added.
> 
> I will update the commit texts accordingly and resend the whole series since
> this should be then mentioned in every commit to make sure it is not missed.

Actually on the second thought: does the above memory ordering differences
really apply when  we have ARCH_HAS_REFCOUNT? To me it looks like the way
how it is currently implemented for x86 is the same way as it is for atomic cases.


> 
> Best Regards,
> Elena.
> 
> >
> > Thanks,
> >
> > 	tglx

[toc] | [prev] | [next] | [standalone]


#1725016 — Re: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t

FromPeter Zijlstra <peterz@infradead.org>
Date2017-09-01 14:40 +0200
SubjectRe: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t
Message-ID<ukToS-4zk-3@gated-at.bofh.it>
In reply to#1724971
On Fri, Sep 01, 2017 at 11:05:33AM +0000, Reshetova, Elena wrote:
> Actually on the second thought: does the above memory ordering differences
> really apply when  we have ARCH_HAS_REFCOUNT? To me it looks like the way
> how it is currently implemented for x86 is the same way as it is for atomic cases.

Never look to x86 for memory ordering, its boring.

And yes, for the ARM implementation it can certainly make a difference.

[toc] | [prev] | [next] | [standalone]


#1725054 — RE: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t

From"Reshetova, Elena" <elena.reshetova@intel.com>
Date2017-09-01 15:30 +0200
SubjectRE: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t
Message-ID<ukUbg-5pL-47@gated-at.bofh.it>
In reply to#1725016
> On Fri, Sep 01, 2017 at 11:05:33AM +0000, Reshetova, Elena wrote:
> > Actually on the second thought: does the above memory ordering differences
> > really apply when  we have ARCH_HAS_REFCOUNT? To me it looks like the way
> > how it is currently implemented for x86 is the same way as it is for atomic cases.
> 
> Never look to x86 for memory ordering, its boring.
> 
> And yes, for the ARM implementation it can certainly make a difference.

So, yes, what I am trying to say is that it can really depend if you have ARCH_HAS_REFCOUNT
enabled or not and then also based on architecture. Thus I believe is also true for atomic: there
might be differences when you use arch. dependent version of function or not. 

So, I guess if I rewrite the commits, I should only include the statement on relaxed memory order
for REFCOUNT_FULL and tell that arch. specific implementations may vary on their properties
(as they do now). 

[toc] | [prev] | [next] | [standalone]


#1725089 — Re: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t

FromPeter Zijlstra <peterz@infradead.org>
Date2017-09-01 15:40 +0200
SubjectRe: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t
Message-ID<ukUkX-5wR-53@gated-at.bofh.it>
In reply to#1725054
On Fri, Sep 01, 2017 at 01:24:16PM +0000, Reshetova, Elena wrote:
> 
> > On Fri, Sep 01, 2017 at 11:05:33AM +0000, Reshetova, Elena wrote:
> > > Actually on the second thought: does the above memory ordering differences
> > > really apply when  we have ARCH_HAS_REFCOUNT? To me it looks like the way
> > > how it is currently implemented for x86 is the same way as it is for atomic cases.
> > 
> > Never look to x86 for memory ordering, its boring.
> > 
> > And yes, for the ARM implementation it can certainly make a difference.
> 
> So, yes, what I am trying to say is that it can really depend if you have ARCH_HAS_REFCOUNT
> enabled or not and then also based on architecture. Thus I believe is also true for atomic: there
> might be differences when you use arch. dependent version of function or not. 

So the generic one in lib/refcount.c is already weaker on ARM, they
don't need to do a ARCH specific 'fast' implementation for the
difference to show up.

[toc] | [prev] | [next] | [standalone]


#1725239 — RE: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t

From"Reshetova, Elena" <elena.reshetova@intel.com>
Date2017-09-01 19:10 +0200
SubjectRE: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t
Message-ID<ukXCa-81A-13@gated-at.bofh.it>
In reply to#1725089
> On Fri, Sep 01, 2017 at 01:24:16PM +0000, Reshetova, Elena wrote:
> >
> > > On Fri, Sep 01, 2017 at 11:05:33AM +0000, Reshetova, Elena wrote:
> > > > Actually on the second thought: does the above memory ordering differences
> > > > really apply when  we have ARCH_HAS_REFCOUNT? To me it looks like the way
> > > > how it is currently implemented for x86 is the same way as it is for atomic
> cases.
> > >
> > > Never look to x86 for memory ordering, its boring.
> > >
> > > And yes, for the ARM implementation it can certainly make a difference.
> >
> > So, yes, what I am trying to say is that it can really depend if you have
> ARCH_HAS_REFCOUNT
> > enabled or not and then also based on architecture. Thus I believe is also true for
> atomic: there
> > might be differences when you use arch. dependent version of function or not.
> 
> So the generic one in lib/refcount.c is already weaker on ARM, they
> don't need to do a ARCH specific 'fast' implementation for the
> difference to show up.

But can they make "fast" implementation on ARM that would give stronger memory guarantees?

[toc] | [prev] | [next] | [standalone]


#1725299 — Re: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t

FromPeter Zijlstra <peterz@infradead.org>
Date2017-09-01 21:20 +0200
SubjectRe: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t
Message-ID<ukZDX-RU-3@gated-at.bofh.it>
In reply to#1725239
On Fri, Sep 01, 2017 at 05:03:55PM +0000, Reshetova, Elena wrote:
> > On Fri, Sep 01, 2017 at 01:24:16PM +0000, Reshetova, Elena wrote:
> > >
> > > > On Fri, Sep 01, 2017 at 11:05:33AM +0000, Reshetova, Elena wrote:
> > > > > Actually on the second thought: does the above memory ordering differences
> > > > > really apply when  we have ARCH_HAS_REFCOUNT? To me it looks like the way
> > > > > how it is currently implemented for x86 is the same way as it is for atomic
> > cases.
> > > >
> > > > Never look to x86 for memory ordering, its boring.
> > > >
> > > > And yes, for the ARM implementation it can certainly make a difference.
> > >
> > > So, yes, what I am trying to say is that it can really depend if you have
> > ARCH_HAS_REFCOUNT
> > > enabled or not and then also based on architecture. Thus I believe is also true for
> > atomic: there
> > > might be differences when you use arch. dependent version of function or not.
> > 
> > So the generic one in lib/refcount.c is already weaker on ARM, they
> > don't need to do a ARCH specific 'fast' implementation for the
> > difference to show up.
> 
> But can they make "fast" implementation on ARM that would give stronger memory guarantees?

Whatever for?

[toc] | [prev] | [next] | [standalone]


#1725986 — RE: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t

From"Reshetova, Elena" <elena.reshetova@intel.com>
Date2017-09-04 12:40 +0200
SubjectRE: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t
Message-ID<ulWXo-4m6-7@gated-at.bofh.it>
In reply to#1725299

> -----Original Message-----
> From: Peter Zijlstra [mailto:peterz@infradead.org]
> Sent: Friday, September 1, 2017 10:13 PM
> To: Reshetova, Elena <elena.reshetova@intel.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>; linux-kernel@vger.kernel.org; linux-
> fsdevel@vger.kernel.org; gregkh@linuxfoundation.org; viro@zeniv.linux.org.uk;
> tj@kernel.org; mingo@redhat.com; hannes@cmpxchg.org; lizefan@huawei.com;
> acme@kernel.org; alexander.shishkin@linux.intel.com; eparis@redhat.com;
> akpm@linux-foundation.org; arnd@arndb.de; luto@kernel.org;
> keescook@chromium.org; dvhart@infradead.org; ebiederm@xmission.com
> Subject: Re: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t
> 
> On Fri, Sep 01, 2017 at 05:03:55PM +0000, Reshetova, Elena wrote:
> > > On Fri, Sep 01, 2017 at 01:24:16PM +0000, Reshetova, Elena wrote:
> > > >
> > > > > On Fri, Sep 01, 2017 at 11:05:33AM +0000, Reshetova, Elena wrote:
> > > > > > Actually on the second thought: does the above memory ordering
> differences
> > > > > > really apply when  we have ARCH_HAS_REFCOUNT? To me it looks like the
> way
> > > > > > how it is currently implemented for x86 is the same way as it is for atomic
> > > cases.
> > > > >
> > > > > Never look to x86 for memory ordering, its boring.
> > > > >
> > > > > And yes, for the ARM implementation it can certainly make a difference.
> > > >
> > > > So, yes, what I am trying to say is that it can really depend if you have
> > > ARCH_HAS_REFCOUNT
> > > > enabled or not and then also based on architecture. Thus I believe is also true
> for
> > > atomic: there
> > > > might be differences when you use arch. dependent version of function or not.
> > >
> > > So the generic one in lib/refcount.c is already weaker on ARM, they
> > > don't need to do a ARCH specific 'fast' implementation for the
> > > difference to show up.
> >
> > But can they make "fast" implementation on ARM that would give stronger
> memory guarantees?
> 
> Whatever for?

Well, maybe just by default when arch.-specific implementation is done. But I was just trying to speculate
to understand. I will resend this one with new comment added. 

Still not sure if I need to resend the whole series with updated commits
or break this up by individual patches further for the separate merges. 

[toc] | [prev] | [next] | [standalone]


#1726025 — Re: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t

FromPeter Zijlstra <peterz@infradead.org>
Date2017-09-04 14:10 +0200
SubjectRe: [PATCH 14/15] futex: convert futex_pi_state.refcount to refcount_t
Message-ID<ulYmu-5lg-13@gated-at.bofh.it>
In reply to#1725986
On Mon, Sep 04, 2017 at 10:31:54AM +0000, Reshetova, Elena wrote:
> > > But can they make "fast" implementation on ARM that would give stronger
> > > memory guarantees?
> > 
> > Whatever for?
> 
> Well, maybe just by default when arch.-specific implementation is
> done. But I was just trying to speculate to understand. I will resend
> this one with new comment added. 

So the generic lib/refcount.c already has weak ordering. It doesn't make
sense for an arch specific implementation (on a weakly ordered machine)
to provide stronger guarantees (it would make things slower).

The weaker ordering of the refcount_t primitives is sufficient if we're
talking pure refcounts. If for some reason code relies on stronger
ordering there _SHOULD_ be a comment with describing the additional
ordering requirements.

But that's a fairly big 'should'. I can well imagine the comment not
being there. In fact, see below.

> Still not sure if I need to resend the whole series with updated
> commits or break this up by individual patches further for the
> separate merges. 

I've yet to look at the ones targeted at subsystems I do, I'm forever
and terminally behind on review :/

I called out the issue on futex in particular because it is fairly
tricky code that.

Now Thomas would like you to mention the fact that refcount_t doesn't
provide the exact same ordering as the atomic_t usages it replaces and
I think it would be good if you could hand-wave an argument on why the
futex code doesn't care.


Now, suppose we were to convert i_count to refcount_t (yes, I know, my
initial conversion wasn't well received), then we need to add
futex_get_inode() similar to futex_get_mm().

That is, smp_mb__{before,after}_atomic() works as expected and can be
used to fortify the implied barriers by refcount_t.

---
Subject: fs,inode: Add comment explaining additional ordering

Add a note to ihold() to document the ordering futex relies upon.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 fs/inode.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/inode.c b/fs/inode.c
index 50370599e371..17192ba92fef 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -395,6 +395,10 @@ void __iget(struct inode *inode)
  */
 void ihold(struct inode *inode)
 {
+	/*
+	 * Note: futex.c:get_futex_key_refs() relies on this function
+	 * implying an smp_mb().
+	 */
 	WARN_ON(atomic_inc_return(&inode->i_count) < 2);
 }
 EXPORT_SYMBOL(ihold);

[toc] | [prev] | [next] | [standalone]


#1723263 — [PATCH 07/15] perf: convert perf_event_context.refcount to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-08-30 14:30 +0200
Subject[PATCH 07/15] perf: convert perf_event_context.refcount to refcount_t
Message-ID<ukai7-8hx-51@gated-at.bofh.it>
In reply to#1723259
atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable perf_event_context.refcount is used as pure reference counter.
Convert it to refcount_t and fix up the operations.

Suggested-by: Kees Cook <keescook@chromium.org>
Reviewed-by: David Windsor <dwindsor@gmail.com>
Reviewed-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
---
 include/linux/perf_event.h |  3 ++-
 kernel/events/core.c       | 12 ++++++------
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 9bac4bf..75c11181 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -54,6 +54,7 @@ struct perf_guest_info_callbacks {
 #include <linux/perf_regs.h>
 #include <linux/workqueue.h>
 #include <linux/cgroup.h>
+#include <linux/refcount.h>
 #include <asm/local.h>
 
 struct perf_callchain_entry {
@@ -737,7 +738,7 @@ struct perf_event_context {
 	int				nr_stat;
 	int				nr_freq;
 	int				rotate_disable;
-	atomic_t			refcount;
+	refcount_t			refcount;
 	struct task_struct		*task;
 
 	/*
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 852768d..57ef7ce 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -1109,7 +1109,7 @@ static void perf_event_ctx_deactivate(struct perf_event_context *ctx)
 
 static void get_ctx(struct perf_event_context *ctx)
 {
-	WARN_ON(!atomic_inc_not_zero(&ctx->refcount));
+	WARN_ON(!refcount_inc_not_zero(&ctx->refcount));
 }
 
 static void free_ctx(struct rcu_head *head)
@@ -1123,7 +1123,7 @@ static void free_ctx(struct rcu_head *head)
 
 static void put_ctx(struct perf_event_context *ctx)
 {
-	if (atomic_dec_and_test(&ctx->refcount)) {
+	if (refcount_dec_and_test(&ctx->refcount)) {
 		if (ctx->parent_ctx)
 			put_ctx(ctx->parent_ctx);
 		if (ctx->task && ctx->task != TASK_TOMBSTONE)
@@ -1201,7 +1201,7 @@ perf_event_ctx_lock_nested(struct perf_event *event, int nesting)
 again:
 	rcu_read_lock();
 	ctx = ACCESS_ONCE(event->ctx);
-	if (!atomic_inc_not_zero(&ctx->refcount)) {
+	if (!refcount_inc_not_zero(&ctx->refcount)) {
 		rcu_read_unlock();
 		goto again;
 	}
@@ -1329,7 +1329,7 @@ perf_lock_task_context(struct task_struct *task, int ctxn, unsigned long *flags)
 		}
 
 		if (ctx->task == TASK_TOMBSTONE ||
-		    !atomic_inc_not_zero(&ctx->refcount)) {
+		    !refcount_inc_not_zero(&ctx->refcount)) {
 			raw_spin_unlock(&ctx->lock);
 			ctx = NULL;
 		} else {
@@ -3795,7 +3795,7 @@ static void __perf_event_init_context(struct perf_event_context *ctx)
 	INIT_LIST_HEAD(&ctx->pinned_groups);
 	INIT_LIST_HEAD(&ctx->flexible_groups);
 	INIT_LIST_HEAD(&ctx->event_list);
-	atomic_set(&ctx->refcount, 1);
+	refcount_set(&ctx->refcount, 1);
 }
 
 static struct perf_event_context *
@@ -9812,7 +9812,7 @@ __perf_event_ctx_lock_double(struct perf_event *group_leader,
 again:
 	rcu_read_lock();
 	gctx = READ_ONCE(group_leader->ctx);
-	if (!atomic_inc_not_zero(&gctx->refcount)) {
+	if (!refcount_inc_not_zero(&gctx->refcount)) {
 		rcu_read_unlock();
 		goto again;
 	}
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1723264 — [PATCH 03/15] sched: convert user_struct.__count to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-08-30 14:30 +0200
Subject[PATCH 03/15] sched: convert user_struct.__count to refcount_t
Message-ID<ukai7-8hx-47@gated-at.bofh.it>
In reply to#1723259
atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable user_struct.__count is used as pure reference counter.
Convert it to refcount_t and fix up the operations.

Suggested-by: Kees Cook <keescook@chromium.org>
Reviewed-by: David Windsor <dwindsor@gmail.com>
Reviewed-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
---
 include/linux/sched/user.h | 5 +++--
 kernel/user.c              | 8 ++++----
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/include/linux/sched/user.h b/include/linux/sched/user.h
index 3c07e41..afcbf19 100644
--- a/include/linux/sched/user.h
+++ b/include/linux/sched/user.h
@@ -3,6 +3,7 @@
 
 #include <linux/uidgid.h>
 #include <linux/atomic.h>
+#include <linux/refcount.h>
 
 struct key;
 
@@ -10,7 +11,7 @@ struct key;
  * Some day this will be a full-fledged user tracking system..
  */
 struct user_struct {
-	atomic_t __count;	/* reference count */
+	refcount_t __count;	/* reference count */
 	atomic_t processes;	/* How many processes does this user have? */
 	atomic_t sigpending;	/* How many pending signals does this user have? */
 #ifdef CONFIG_FANOTIFY
@@ -54,7 +55,7 @@ extern struct user_struct root_user;
 extern struct user_struct * alloc_uid(kuid_t);
 static inline struct user_struct *get_uid(struct user_struct *u)
 {
-	atomic_inc(&u->__count);
+	refcount_inc(&u->__count);
 	return u;
 }
 extern void free_uid(struct user_struct *);
diff --git a/kernel/user.c b/kernel/user.c
index 00281ad..c072348 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -90,7 +90,7 @@ static DEFINE_SPINLOCK(uidhash_lock);
 
 /* root_user.__count is 1, for init task cred */
 struct user_struct root_user = {
-	.__count	= ATOMIC_INIT(1),
+	.__count	= REFCOUNT_INIT(1),
 	.processes	= ATOMIC_INIT(1),
 	.sigpending	= ATOMIC_INIT(0),
 	.locked_shm     = 0,
@@ -116,7 +116,7 @@ static struct user_struct *uid_hash_find(kuid_t uid, struct hlist_head *hashent)
 
 	hlist_for_each_entry(user, hashent, uidhash_node) {
 		if (uid_eq(user->uid, uid)) {
-			atomic_inc(&user->__count);
+			refcount_inc(&user->__count);
 			return user;
 		}
 	}
@@ -163,7 +163,7 @@ void free_uid(struct user_struct *up)
 		return;
 
 	local_irq_save(flags);
-	if (atomic_dec_and_lock(&up->__count, &uidhash_lock))
+	if (refcount_dec_and_lock(&up->__count, &uidhash_lock))
 		free_user(up, flags);
 	else
 		local_irq_restore(flags);
@@ -184,7 +184,7 @@ struct user_struct *alloc_uid(kuid_t uid)
 			goto out_unlock;
 
 		new->uid = uid;
-		atomic_set(&new->__count, 1);
+		refcount_set(&new->__count, 1);
 
 		/*
 		 * Before adding this, check whether we raced
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1723266 — [PATCH 11/15] nsproxy: convert nsproxy.count to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-08-30 14:30 +0200
Subject[PATCH 11/15] nsproxy: convert nsproxy.count to refcount_t
Message-ID<ukai7-8hx-55@gated-at.bofh.it>
In reply to#1723259
atomic_t variables are currently used to implement reference
counters with the following properties:
 - counter is initialized to 1 using atomic_set()
 - a resource is freed upon counter reaching zero
 - once counter reaches zero, its further
   increments aren't allowed
 - counter schema uses basic atomic operations
   (set, inc, inc_not_zero, dec_and_test, etc.)

Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.

The variable nsproxy.count is used as pure reference counter.
Convert it to refcount_t and fix up the operations.

Suggested-by: Kees Cook <keescook@chromium.org>
Reviewed-by: David Windsor <dwindsor@gmail.com>
Reviewed-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
---
 include/linux/nsproxy.h | 6 +++---
 kernel/nsproxy.c        | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
index ac0d65b..f862ba8 100644
--- a/include/linux/nsproxy.h
+++ b/include/linux/nsproxy.h
@@ -28,7 +28,7 @@ struct fs_struct;
  * nsproxy is copied.
  */
 struct nsproxy {
-	atomic_t count;
+	refcount_t count;
 	struct uts_namespace *uts_ns;
 	struct ipc_namespace *ipc_ns;
 	struct mnt_namespace *mnt_ns;
@@ -74,14 +74,14 @@ int __init nsproxy_cache_init(void);
 
 static inline void put_nsproxy(struct nsproxy *ns)
 {
-	if (atomic_dec_and_test(&ns->count)) {
+	if (refcount_dec_and_test(&ns->count)) {
 		free_nsproxy(ns);
 	}
 }
 
 static inline void get_nsproxy(struct nsproxy *ns)
 {
-	atomic_inc(&ns->count);
+	refcount_inc(&ns->count);
 }
 
 #endif
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index f6c5d33..5bfe691 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -31,7 +31,7 @@
 static struct kmem_cache *nsproxy_cachep;
 
 struct nsproxy init_nsproxy = {
-	.count			= ATOMIC_INIT(1),
+	.count			= REFCOUNT_INIT(1),
 	.uts_ns			= &init_uts_ns,
 #if defined(CONFIG_POSIX_MQUEUE) || defined(CONFIG_SYSVIPC)
 	.ipc_ns			= &init_ipc_ns,
@@ -52,7 +52,7 @@ static inline struct nsproxy *create_nsproxy(void)
 
 	nsproxy = kmem_cache_alloc(nsproxy_cachep, GFP_KERNEL);
 	if (nsproxy)
-		atomic_set(&nsproxy->count, 1);
+		refcount_set(&nsproxy->count, 1);
 	return nsproxy;
 }
 
@@ -225,7 +225,7 @@ void switch_task_namespaces(struct task_struct *p, struct nsproxy *new)
 	p->nsproxy = new;
 	task_unlock(p);
 
-	if (ns && atomic_dec_and_test(&ns->count))
+	if (ns && refcount_dec_and_test(&ns->count))
 		free_nsproxy(ns);
 }
 
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1724678

FromKees Cook <keescook@chromium.org>
Date2017-09-01 01:50 +0200
Message-ID<ukHnI-41L-27@gated-at.bofh.it>
In reply to#1723259
On Wed, Aug 30, 2017 at 5:22 AM, Elena Reshetova
<elena.reshetova@intel.com> wrote:
> Now we have at least x86 support for ARCH_HAS_REFCOUNT merged and
> arm and others on their way.
>
> Changes in v5:
>  * Kees catched that the following changes in
>    perf_event_context.refcount and futex_pi_state.refcount
>    are not correct now when ARCH_HAS_REFCOUNT is enabled:
>     -   WARN_ON(!atomic_inc_not_zero(refcount));
>     +   refcount_inc(refcount);
>    So they are now changed back to using refcount_inc_not_zero.

Thanks!

Reviewed-by: Kees Cook <keescook@chromium.org>

Andrew, are you able to carry these patches in -mm, since they span a
bunch of core kernel areas?

-Kees

>
> Changes in v4:
>  * just rebase and corrections on linux-next/master
>
> Changes in v3:
>  * SoB chain corrected
>  * minor corrections based on v2 feedback
>  * rebase on linux-next/master as of today
>
> Changes in v2:
>  * dropped already merged patches
>  * rebase on top of linux-next/master
>  * Now by default refcount_t = atomic_t (*) and uses all atomic
>    standard operations unless CONFIG_REFCOUNT_FULL is enabled.
>    This is a compromise for the systems that are critical on
>    performance (such as net) and cannot accept even slight delay
>    on the refcounter operations.
>
> This series, for core kernel components, replaces atomic_t reference
> counters with the new refcount_t type and API (see include/linux/refcount.h).
> By doing this we prevent intentional or accidental
> underflows or overflows that can led to use-after-free vulnerabilities.
>
> The patches are fully independent and can be cherry-picked separately.
> If there are no objections to the patches, please merge them via respective trees.
>
>
> Elena Reshetova (15):
>   sched: convert sighand_struct.count to refcount_t
>   sched: convert signal_struct.sigcnt to refcount_t
>   sched: convert user_struct.__count to refcount_t
>   sched: convert numa_group.refcount to refcount_t
>   sched/task_struct: convert task_struct.usage to refcount_t
>   sched/task_struct: convert task_struct.stack_refcount to refcount_t
>   perf: convert perf_event_context.refcount to refcount_t
>   perf/ring_buffer: convert ring_buffer.refcount to refcount_t
>   perf/ring_buffer: convert ring_buffer.aux_refcount to refcount_t
>   uprobes: convert uprobe.ref to refcount_t
>   nsproxy: convert nsproxy.count to refcount_t
>   groups: convert group_info.usage to refcount_t
>   creds: convert cred.usage to refcount_t
>   futex: convert futex_pi_state.refcount to refcount_t
>   kcov: convert kcov.refcount to refcount_t
>
>  fs/exec.c                        |  4 ++--
>  fs/proc/task_nommu.c             |  2 +-
>  include/linux/cred.h             | 13 ++++++------
>  include/linux/init_task.h        |  7 +++---
>  include/linux/nsproxy.h          |  6 +++---
>  include/linux/perf_event.h       |  3 ++-
>  include/linux/sched.h            |  5 +++--
>  include/linux/sched/signal.h     |  5 +++--
>  include/linux/sched/task.h       |  4 ++--
>  include/linux/sched/task_stack.h |  2 +-
>  include/linux/sched/user.h       |  5 +++--
>  kernel/cred.c                    | 46 ++++++++++++++++++++--------------------
>  kernel/events/core.c             | 18 ++++++++--------
>  kernel/events/internal.h         |  5 +++--
>  kernel/events/ring_buffer.c      |  8 +++----
>  kernel/events/uprobes.c          |  8 +++----
>  kernel/fork.c                    | 24 ++++++++++-----------
>  kernel/futex.c                   | 13 ++++++------
>  kernel/groups.c                  |  2 +-
>  kernel/kcov.c                    |  9 ++++----
>  kernel/nsproxy.c                 |  6 +++---
>  kernel/sched/fair.c              | 12 +++++------
>  kernel/user.c                    |  8 +++----
>  23 files changed, 112 insertions(+), 103 deletions(-)
>
> --
> 2.7.4
>



-- 
Kees Cook
Pixel Security

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | linux.kernel


csiph-web