lkml.org 
[lkml]   [2020]   [Feb]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.5 506/542] ocfs2: fix a NULL pointer dereference when call ocfs2_update_inode_fsync_trans()
    Date
    From: wangyan <wangyan122@huawei.com>

    [ Upstream commit 9f16ca48fc818a17de8be1f75d08e7f4addc4497 ]

    I found a NULL pointer dereference in ocfs2_update_inode_fsync_trans(),
    handle->h_transaction may be NULL in this situation:

    ocfs2_file_write_iter
    ->__generic_file_write_iter
    ->generic_perform_write
    ->ocfs2_write_begin
    ->ocfs2_write_begin_nolock
    ->ocfs2_write_cluster_by_desc
    ->ocfs2_write_cluster
    ->ocfs2_mark_extent_written
    ->ocfs2_change_extent_flag
    ->ocfs2_split_extent
    ->ocfs2_try_to_merge_extent
    ->ocfs2_extend_rotate_transaction
    ->ocfs2_extend_trans
    ->jbd2_journal_restart
    ->jbd2__journal_restart
    // handle->h_transaction is NULL here
    ->handle->h_transaction = NULL;
    ->start_this_handle
    /* journal aborted due to storage
    network disconnection, return error */
    ->return -EROFS;
    /* line 3806 in ocfs2_try_to_merge_extent (),
    it will ignore ret error. */
    ->ret = 0;
    ->...
    ->ocfs2_write_end
    ->ocfs2_write_end_nolock
    ->ocfs2_update_inode_fsync_trans
    // NULL pointer dereference
    ->oi->i_sync_tid = handle->h_transaction->t_tid;

    The information of NULL pointer dereference as follows:
    JBD2: Detected IO errors while flushing file data on dm-11-45
    Aborting journal on device dm-11-45.
    JBD2: Error -5 detected when updating journal superblock for dm-11-45.
    (dd,22081,3):ocfs2_extend_trans:474 ERROR: status = -30
    (dd,22081,3):ocfs2_try_to_merge_extent:3877 ERROR: status = -30
    Unable to handle kernel NULL pointer dereference at
    virtual address 0000000000000008
    Mem abort info:
    ESR = 0x96000004
    Exception class = DABT (current EL), IL = 32 bits
    SET = 0, FnV = 0
    EA = 0, S1PTW = 0
    Data abort info:
    ISV = 0, ISS = 0x00000004
    CM = 0, WnR = 0
    user pgtable: 4k pages, 48-bit VAs, pgdp = 00000000e74e1338
    [0000000000000008] pgd=0000000000000000
    Internal error: Oops: 96000004 [#1] SMP
    Process dd (pid: 22081, stack limit = 0x00000000584f35a9)
    CPU: 3 PID: 22081 Comm: dd Kdump: loaded
    Hardware name: Huawei TaiShan 2280 V2/BC82AMDD, BIOS 0.98 08/25/2019
    pstate: 60400009 (nZCv daif +PAN -UAO)
    pc : ocfs2_write_end_nolock+0x2b8/0x550 [ocfs2]
    lr : ocfs2_write_end_nolock+0x2a0/0x550 [ocfs2]
    sp : ffff0000459fba70
    x29: ffff0000459fba70 x28: 0000000000000000
    x27: ffff807ccf7f1000 x26: 0000000000000001
    x25: ffff807bdff57970 x24: ffff807caf1d4000
    x23: ffff807cc79e9000 x22: 0000000000001000
    x21: 000000006c6cd000 x20: ffff0000091d9000
    x19: ffff807ccb239db0 x18: ffffffffffffffff
    x17: 000000000000000e x16: 0000000000000007
    x15: ffff807c5e15bd78 x14: 0000000000000000
    x13: 0000000000000000 x12: 0000000000000000
    x11: 0000000000000000 x10: 0000000000000001
    x9 : 0000000000000228 x8 : 000000000000000c
    x7 : 0000000000000fff x6 : ffff807a308ed6b0
    x5 : ffff7e01f10967c0 x4 : 0000000000000018
    x3 : d0bc661572445600 x2 : 0000000000000000
    x1 : 000000001b2e0200 x0 : 0000000000000000
    Call trace:
    ocfs2_write_end_nolock+0x2b8/0x550 [ocfs2]
    ocfs2_write_end+0x4c/0x80 [ocfs2]
    generic_perform_write+0x108/0x1a8
    __generic_file_write_iter+0x158/0x1c8
    ocfs2_file_write_iter+0x668/0x950 [ocfs2]
    __vfs_write+0x11c/0x190
    vfs_write+0xac/0x1c0
    ksys_write+0x6c/0xd8
    __arm64_sys_write+0x24/0x30
    el0_svc_common+0x78/0x130
    el0_svc_handler+0x38/0x78
    el0_svc+0x8/0xc

    To prevent NULL pointer dereference in this situation, we use
    is_handle_aborted() before using handle->h_transaction->t_tid.

    Link: http://lkml.kernel.org/r/03e750ab-9ade-83aa-b000-b9e81e34e539@huawei.com
    Signed-off-by: Yan Wang <wangyan122@huawei.com>
    Reviewed-by: Jun Piao <piaojun@huawei.com>
    Cc: Mark Fasheh <mark@fasheh.com>
    Cc: Joel Becker <jlbec@evilplan.org>
    Cc: Junxiao Bi <junxiao.bi@oracle.com>
    Cc: Joseph Qi <jiangqi903@gmail.com>
    Cc: Changwei Ge <gechangwei@live.cn>
    Cc: Gang He <ghe@suse.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/ocfs2/journal.h | 8 +++++---
    1 file changed, 5 insertions(+), 3 deletions(-)

    diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h
    index 3103ba7f97a28..bfe611ed1b1d7 100644
    --- a/fs/ocfs2/journal.h
    +++ b/fs/ocfs2/journal.h
    @@ -597,9 +597,11 @@ static inline void ocfs2_update_inode_fsync_trans(handle_t *handle,
    {
    struct ocfs2_inode_info *oi = OCFS2_I(inode);

    - oi->i_sync_tid = handle->h_transaction->t_tid;
    - if (datasync)
    - oi->i_datasync_tid = handle->h_transaction->t_tid;
    + if (!is_handle_aborted(handle)) {
    + oi->i_sync_tid = handle->h_transaction->t_tid;
    + if (datasync)
    + oi->i_datasync_tid = handle->h_transaction->t_tid;
    + }
    }

    #endif /* OCFS2_JOURNAL_H */
    --
    2.20.1
    \
     
     \ /
      Last update: 2020-02-14 17:00    [W:2.367 / U:0.160 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site