lkml.org 
[lkml]   [2018]   [Mar]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 124/134] fs/aio: Use RCU accessors for kioctx_table->table[]
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Tejun Heo <tj@kernel.org>

    commit d0264c01e7587001a8c4608a5d1818dba9a4c11a upstream.

    While converting ioctx index from a list to a table, db446a08c23d
    ("aio: convert the ioctx list to table lookup v3") missed tagging
    kioctx_table->table[] as an array of RCU pointers and using the
    appropriate RCU accessors. This introduces a small window in the
    lookup path where init and access may race.

    Mark kioctx_table->table[] with __rcu and use the approriate RCU
    accessors when using the field.

    Signed-off-by: Tejun Heo <tj@kernel.org>
    Reported-by: Jann Horn <jannh@google.com>
    Fixes: db446a08c23d ("aio: convert the ioctx list to table lookup v3")
    Cc: Benjamin LaHaise <bcrl@kvack.org>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: stable@vger.kernel.org # v3.12+
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/aio.c | 21 +++++++++++----------
    1 file changed, 11 insertions(+), 10 deletions(-)

    --- a/fs/aio.c
    +++ b/fs/aio.c
    @@ -68,9 +68,9 @@ struct aio_ring {
    #define AIO_RING_PAGES 8

    struct kioctx_table {
    - struct rcu_head rcu;
    - unsigned nr;
    - struct kioctx *table[];
    + struct rcu_head rcu;
    + unsigned nr;
    + struct kioctx __rcu *table[];
    };

    struct kioctx_cpu {
    @@ -327,7 +327,7 @@ static int aio_ring_mremap(struct vm_are
    for (i = 0; i < table->nr; i++) {
    struct kioctx *ctx;

    - ctx = table->table[i];
    + ctx = rcu_dereference(table->table[i]);
    if (ctx && ctx->aio_ring_file == file) {
    if (!atomic_read(&ctx->dead)) {
    ctx->user_id = ctx->mmap_base = vma->vm_start;
    @@ -651,9 +651,9 @@ static int ioctx_add_table(struct kioctx
    while (1) {
    if (table)
    for (i = 0; i < table->nr; i++)
    - if (!table->table[i]) {
    + if (!rcu_access_pointer(table->table[i])) {
    ctx->id = i;
    - table->table[i] = ctx;
    + rcu_assign_pointer(table->table[i], ctx);
    spin_unlock(&mm->ioctx_lock);

    /* While kioctx setup is in progress,
    @@ -828,8 +828,8 @@ static int kill_ioctx(struct mm_struct *
    }

    table = rcu_dereference_raw(mm->ioctx_table);
    - WARN_ON(ctx != table->table[ctx->id]);
    - table->table[ctx->id] = NULL;
    + WARN_ON(ctx != rcu_access_pointer(table->table[ctx->id]));
    + RCU_INIT_POINTER(table->table[ctx->id], NULL);
    spin_unlock(&mm->ioctx_lock);

    /* free_ioctx_reqs() will do the necessary RCU synchronization */
    @@ -874,7 +874,8 @@ void exit_aio(struct mm_struct *mm)

    skipped = 0;
    for (i = 0; i < table->nr; ++i) {
    - struct kioctx *ctx = table->table[i];
    + struct kioctx *ctx =
    + rcu_dereference_protected(table->table[i], true);

    if (!ctx) {
    skipped++;
    @@ -1063,7 +1064,7 @@ static struct kioctx *lookup_ioctx(unsig
    if (!table || id >= table->nr)
    goto out;

    - ctx = table->table[id];
    + ctx = rcu_dereference(table->table[id]);
    if (ctx && ctx->user_id == ctx_id) {
    percpu_ref_get(&ctx->users);
    ret = ctx;

    \
     
     \ /
      Last update: 2018-03-19 19:18    [W:4.072 / U:0.164 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site