lkml.org 
[lkml]   [2018]   [Oct]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.14 13/32] ucma: fix a use-after-free in ucma_resolve_ip()
    Date
    From: Cong Wang <xiyou.wangcong@gmail.com>

    [ Upstream commit 5fe23f262e0548ca7f19fb79f89059a60d087d22 ]

    There is a race condition between ucma_close() and ucma_resolve_ip():

    CPU0 CPU1
    ucma_resolve_ip(): ucma_close():

    ctx = ucma_get_ctx(file, cmd.id);

    list_for_each_entry_safe(ctx, tmp, &file->ctx_list, list) {
    mutex_lock(&mut);
    idr_remove(&ctx_idr, ctx->id);
    mutex_unlock(&mut);
    ...
    mutex_lock(&mut);
    if (!ctx->closing) {
    mutex_unlock(&mut);
    rdma_destroy_id(ctx->cm_id);
    ...
    ucma_free_ctx(ctx);

    ret = rdma_resolve_addr();
    ucma_put_ctx(ctx);

    Before idr_remove(), ucma_get_ctx() could still find the ctx
    and after rdma_destroy_id(), rdma_resolve_addr() may still
    access id_priv pointer. Also, ucma_put_ctx() may use ctx after
    ucma_free_ctx() too.

    ucma_close() should call ucma_put_ctx() too which tests the
    refcnt and waits for the last one releasing it. The similar
    pattern is already used by ucma_destroy_id().

    Reported-and-tested-by: syzbot+da2591e115d57a9cbb8b@syzkaller.appspotmail.com
    Reported-by: syzbot+cfe3c1e8ef634ba8964b@syzkaller.appspotmail.com
    Cc: Jason Gunthorpe <jgg@mellanox.com>
    Cc: Doug Ledford <dledford@redhat.com>
    Cc: Leon Romanovsky <leon@kernel.org>
    Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
    Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
    Signed-off-by: Doug Ledford <dledford@redhat.com>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    ---
    drivers/infiniband/core/ucma.c | 2 ++
    1 file changed, 2 insertions(+)

    diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
    index a22b992cde38..c1a7ed6306bd 100644
    --- a/drivers/infiniband/core/ucma.c
    +++ b/drivers/infiniband/core/ucma.c
    @@ -1736,6 +1736,8 @@ static int ucma_close(struct inode *inode, struct file *filp)
    mutex_lock(&mut);
    if (!ctx->closing) {
    mutex_unlock(&mut);
    + ucma_put_ctx(ctx);
    + wait_for_completion(&ctx->comp);
    /* rdma_destroy_id ensures that no event handlers are
    * inflight for that id before releasing it.
    */
    --
    2.17.1
    \
     
     \ /
      Last update: 2018-10-08 17:33    [W:2.778 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site