lkml.org 
[lkml]   [2019]   [Apr]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 120/168] 9p: do not trust pdu content for stat item size
    Date
    [ Upstream commit 2803cf4379ed252894f046cb8812a48db35294e3 ]

    v9fs_dir_readdir() could deadloop if a struct was sent with a size set
    to -2

    Link: http://lkml.kernel.org/r/1536134432-11997-1-git-send-email-asmadeus@codewreck.org
    Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88021
    Signed-off-by: Gertjan Halkes <gertjan@google.com>
    Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/9p/vfs_dir.c | 8 +++-----
    net/9p/protocol.c | 3 ++-
    2 files changed, 5 insertions(+), 6 deletions(-)

    diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
    index 7d889f56b8e7..05769219d2c2 100644
    --- a/fs/9p/vfs_dir.c
    +++ b/fs/9p/vfs_dir.c
    @@ -105,7 +105,6 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
    int err = 0;
    struct p9_fid *fid;
    int buflen;
    - int reclen = 0;
    struct p9_rdir *rdir;
    struct kvec kvec;

    @@ -138,11 +137,10 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
    while (rdir->head < rdir->tail) {
    err = p9stat_read(fid->clnt, rdir->buf + rdir->head,
    rdir->tail - rdir->head, &st);
    - if (err) {
    + if (err <= 0) {
    p9_debug(P9_DEBUG_VFS, "returned %d\n", err);
    return -EIO;
    }
    - reclen = st.size+2;

    over = !dir_emit(ctx, st.name, strlen(st.name),
    v9fs_qid2ino(&st.qid), dt_type(&st));
    @@ -150,8 +148,8 @@ static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
    if (over)
    return 0;

    - rdir->head += reclen;
    - ctx->pos += reclen;
    + rdir->head += err;
    + ctx->pos += err;
    }
    }
    }
    diff --git a/net/9p/protocol.c b/net/9p/protocol.c
    index 145f80518064..7f1b45c082c9 100644
    --- a/net/9p/protocol.c
    +++ b/net/9p/protocol.c
    @@ -570,9 +570,10 @@ int p9stat_read(struct p9_client *clnt, char *buf, int len, struct p9_wstat *st)
    if (ret) {
    p9_debug(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret);
    trace_9p_protocol_dump(clnt, &fake_pdu);
    + return ret;
    }

    - return ret;
    + return fake_pdu.offset;
    }
    EXPORT_SYMBOL(p9stat_read);

    --
    2.19.1


    \
     
     \ /
      Last update: 2019-04-24 20:03    [W:7.179 / U:0.612 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site