lkml.org 
[lkml]   [2018]   [Nov]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 4.14 29/30] 9p locks: fix glock.client_id leak in do_lock
    Date
    From: Dominique Martinet <dominique.martinet@cea.fr>

    [ Upstream commit b4dc44b3cac9e8327e0655f530ed0c46f2e6214c ]

    the 9p client code overwrites our glock.client_id pointing to a static
    buffer by an allocated string holding the network provided value which
    we do not care about; free and reset the value as appropriate.

    This is almost identical to the leak in v9fs_file_getlock() fixed by
    Al Viro in commit ce85dd58ad5a6 ("9p: we are leaking glock.client_id
    in v9fs_file_getlock()"), which was returned as an error by a coverity
    false positive -- while we are here attempt to make the code slightly
    more robust to future change of the net/9p/client code and hopefully
    more clear to coverity that there is no problem.

    Link: http://lkml.kernel.org/r/1536339057-21974-5-git-send-email-asmadeus@codewreck.org
    Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/9p/vfs_file.c | 16 ++++++++++++++--
    1 file changed, 14 insertions(+), 2 deletions(-)

    diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
    index 03c9e325bfbc..3a2f37ad1f89 100644
    --- a/fs/9p/vfs_file.c
    +++ b/fs/9p/vfs_file.c
    @@ -204,6 +204,14 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
    break;
    if (schedule_timeout_interruptible(P9_LOCK_TIMEOUT) != 0)
    break;
    + /*
    + * p9_client_lock_dotl overwrites flock.client_id with the
    + * server message, free and reuse the client name
    + */
    + if (flock.client_id != fid->clnt->name) {
    + kfree(flock.client_id);
    + flock.client_id = fid->clnt->name;
    + }
    }

    /* map 9p status to VFS status */
    @@ -235,6 +243,8 @@ static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
    locks_lock_file_wait(filp, fl);
    fl->fl_type = fl_type;
    }
    + if (flock.client_id != fid->clnt->name)
    + kfree(flock.client_id);
    out:
    return res;
    }
    @@ -269,7 +279,7 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)

    res = p9_client_getlock_dotl(fid, &glock);
    if (res < 0)
    - return res;
    + goto out;
    /* map 9p lock type to os lock type */
    switch (glock.type) {
    case P9_LOCK_TYPE_RDLCK:
    @@ -290,7 +300,9 @@ static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
    fl->fl_end = glock.start + glock.length - 1;
    fl->fl_pid = -glock.proc_id;
    }
    - kfree(glock.client_id);
    +out:
    + if (glock.client_id != fid->clnt->name)
    + kfree(glock.client_id);
    return res;
    }

    --
    2.17.1
    \
     
     \ /
      Last update: 2018-11-04 15:00    [W:4.584 / U:0.084 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site