lkml.org 
[lkml]   [2020]   [Apr]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.6 221/254] ocfs2: no need try to truncate file beyond i_size
    Date
    From: Changwei Ge <chge@linux.alibaba.com>

    commit 783fda856e1034dee90a873f7654c418212d12d7 upstream.

    Linux fallocate(2) with FALLOC_FL_PUNCH_HOLE mode set, its offset can
    exceed the inode size. Ocfs2 now doesn't allow that offset beyond inode
    size. This restriction is not necessary and violates fallocate(2)
    semantics.

    If fallocate(2) offset is beyond inode size, just return success and do
    nothing further.

    Otherwise, ocfs2 will crash the kernel.

    kernel BUG at fs/ocfs2//alloc.c:7264!
    ocfs2_truncate_inline+0x20f/0x360 [ocfs2]
    ocfs2_remove_inode_range+0x23c/0xcb0 [ocfs2]
    __ocfs2_change_file_space+0x4a5/0x650 [ocfs2]
    ocfs2_fallocate+0x83/0xa0 [ocfs2]
    vfs_fallocate+0x148/0x230
    SyS_fallocate+0x48/0x80
    do_syscall_64+0x79/0x170

    Signed-off-by: Changwei Ge <chge@linux.alibaba.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
    Cc: Mark Fasheh <mark@fasheh.com>
    Cc: Joel Becker <jlbec@evilplan.org>
    Cc: Junxiao Bi <junxiao.bi@oracle.com>
    Cc: Changwei Ge <gechangwei@live.cn>
    Cc: Gang He <ghe@suse.com>
    Cc: Jun Piao <piaojun@huawei.com>
    Cc: <stable@vger.kernel.org>
    Link: http://lkml.kernel.org/r/20200407082754.17565-1-chge@linux.alibaba.com
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/ocfs2/alloc.c | 4 ++++
    1 file changed, 4 insertions(+)

    --- a/fs/ocfs2/alloc.c
    +++ b/fs/ocfs2/alloc.c
    @@ -7403,6 +7403,10 @@ int ocfs2_truncate_inline(struct inode *
    struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
    struct ocfs2_inline_data *idata = &di->id2.i_data;

    + /* No need to punch hole beyond i_size. */
    + if (start >= i_size_read(inode))
    + return 0;
    +
    if (end > i_size_read(inode))
    end = i_size_read(inode);


    \
     
     \ /
      Last update: 2020-04-16 16:35    [W:4.620 / U:0.076 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site