lkml.org 
[lkml]   [2014]   [Jul]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.8 016/116] UBIFS: fix an mmap and fsync race condition
    Date
    3.8.13.27 -stable review patch.  If anyone has any objections, please let me know.

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

    From: hujianyang <hujianyang@huawei.com>

    commit 691a7c6f28ac90cccd0dbcf81348ea90b211bdd0 upstream.

    There is a race condition in UBIFS:

    Thread A (mmap) Thread B (fsync)

    ->__do_fault ->write_cache_pages
    -> ubifs_vm_page_mkwrite
    -> budget_space
    -> lock_page
    -> release/convert_page_budget
    -> SetPagePrivate
    -> TestSetPageDirty
    -> unlock_page
    -> lock_page
    -> TestClearPageDirty
    -> ubifs_writepage
    -> do_writepage
    -> release_budget
    -> ClearPagePrivate
    -> unlock_page
    -> !(ret & VM_FAULT_LOCKED)
    -> lock_page
    -> set_page_dirty
    -> ubifs_set_page_dirty
    -> TestSetPageDirty (set page dirty without budgeting)
    -> unlock_page

    This leads to situation where we have a diry page but no budget allocated for
    this page, so further write-back may fail with -ENOSPC.

    In this fix we return from page_mkwrite without performing unlock_page. We
    return VM_FAULT_LOCKED instead. After doing this, the race above will not
    happen.

    Signed-off-by: hujianyang <hujianyang@huawei.com>
    Tested-by: Laurence Withers <lwithers@guralp.com>
    Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
    Signed-off-by: Kamal Mostafa <kamal@canonical.com>
    ---
    fs/ubifs/file.c | 3 +--
    1 file changed, 1 insertion(+), 2 deletions(-)

    diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
    index 5bc7781..bc7798d 100644
    --- a/fs/ubifs/file.c
    +++ b/fs/ubifs/file.c
    @@ -1522,8 +1522,7 @@ static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma,
    ubifs_release_dirty_inode_budget(c, ui);
    }

    - unlock_page(page);
    - return 0;
    + return VM_FAULT_LOCKED;

    out_unlock:
    unlock_page(page);
    --
    1.9.1


    \
     
     \ /
      Last update: 2014-07-23 05:21    [W:4.155 / U:0.316 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site