lkml.org 
[lkml]   [2017]   [Oct]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 09/15] perf/ring_buffer: convert ring_buffer.aux_refcount to refcount_t
    Date
    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 ring_buffer.aux_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/events/core.c | 2 +-
    kernel/events/internal.h | 2 +-
    kernel/events/ring_buffer.c | 6 +++---
    3 files changed, 5 insertions(+), 5 deletions(-)

    diff --git a/kernel/events/core.c b/kernel/events/core.c
    index 66d7e18..3848480 100644
    --- a/kernel/events/core.c
    +++ b/kernel/events/core.c
    @@ -5182,7 +5182,7 @@ static void perf_mmap_close(struct vm_area_struct *vma)

    /* this has to be the last one */
    rb_free_aux(rb);
    - WARN_ON_ONCE(atomic_read(&rb->aux_refcount));
    + WARN_ON_ONCE(refcount_read(&rb->aux_refcount));

    mutex_unlock(&event->mmap_mutex);
    }
    diff --git a/kernel/events/internal.h b/kernel/events/internal.h
    index 1cdd9fa..cc5b545 100644
    --- a/kernel/events/internal.h
    +++ b/kernel/events/internal.h
    @@ -48,7 +48,7 @@ struct ring_buffer {
    atomic_t aux_mmap_count;
    unsigned long aux_mmap_locked;
    void (*free_aux)(void *);
    - atomic_t aux_refcount;
    + refcount_t aux_refcount;
    void **aux_pages;
    void *aux_priv;

    diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
    index 86e1379..08838cd6 100644
    --- a/kernel/events/ring_buffer.c
    +++ b/kernel/events/ring_buffer.c
    @@ -357,7 +357,7 @@ void *perf_aux_output_begin(struct perf_output_handle *handle,
    if (!atomic_read(&rb->aux_mmap_count))
    goto err;

    - if (!atomic_inc_not_zero(&rb->aux_refcount))
    + if (!refcount_inc_not_zero(&rb->aux_refcount))
    goto err;

    /*
    @@ -655,7 +655,7 @@ int rb_alloc_aux(struct ring_buffer *rb, struct perf_event *event,
    * we keep a refcount here to make sure either of the two can
    * reference them safely.
    */
    - atomic_set(&rb->aux_refcount, 1);
    + refcount_set(&rb->aux_refcount, 1);

    rb->aux_overwrite = overwrite;
    rb->aux_watermark = watermark;
    @@ -674,7 +674,7 @@ int rb_alloc_aux(struct ring_buffer *rb, struct perf_event *event,

    void rb_free_aux(struct ring_buffer *rb)
    {
    - if (atomic_dec_and_test(&rb->aux_refcount))
    + if (refcount_dec_and_test(&rb->aux_refcount))
    __rb_free_aux(rb);
    }

    --
    2.7.4
    \
     
     \ /
      Last update: 2017-10-22 17:39    [W:2.570 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site