lkml.org 
[lkml]   [2019]   [May]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 264/266] drivers/virt/fsl_hypervisor.c: dereferencing error pointers in ioctl
    Date
    From: Dan Carpenter <dan.carpenter@oracle.com>

    commit c8ea3663f7a8e6996d44500ee818c9330ac4fd88 upstream.

    strndup_user() returns error pointers on error, and then in the error
    handling we pass the error pointers to kfree(). It will cause an Oops.

    Link: http://lkml.kernel.org/r/20181218082003.GD32567@kadam
    Fixes: 6db7199407ca ("drivers/virt: introduce Freescale hypervisor management driver")
    Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
    Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
    Cc: Timur Tabi <timur@freescale.com>
    Cc: Mihai Caraman <mihai.caraman@freescale.com>
    Cc: Kumar Gala <galak@kernel.crashing.org>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/virt/fsl_hypervisor.c | 26 +++++++++++++-------------
    1 file changed, 13 insertions(+), 13 deletions(-)

    --- a/drivers/virt/fsl_hypervisor.c
    +++ b/drivers/virt/fsl_hypervisor.c
    @@ -335,8 +335,8 @@ static long ioctl_dtprop(struct fsl_hv_i
    struct fsl_hv_ioctl_prop param;
    char __user *upath, *upropname;
    void __user *upropval;
    - char *path = NULL, *propname = NULL;
    - void *propval = NULL;
    + char *path, *propname;
    + void *propval;
    int ret = 0;

    /* Get the parameters from the user. */
    @@ -348,32 +348,30 @@ static long ioctl_dtprop(struct fsl_hv_i
    upropval = (void __user *)(uintptr_t)param.propval;

    path = strndup_user(upath, FH_DTPROP_MAX_PATHLEN);
    - if (IS_ERR(path)) {
    - ret = PTR_ERR(path);
    - goto out;
    - }
    + if (IS_ERR(path))
    + return PTR_ERR(path);

    propname = strndup_user(upropname, FH_DTPROP_MAX_PATHLEN);
    if (IS_ERR(propname)) {
    ret = PTR_ERR(propname);
    - goto out;
    + goto err_free_path;
    }

    if (param.proplen > FH_DTPROP_MAX_PROPLEN) {
    ret = -EINVAL;
    - goto out;
    + goto err_free_propname;
    }

    propval = kmalloc(param.proplen, GFP_KERNEL);
    if (!propval) {
    ret = -ENOMEM;
    - goto out;
    + goto err_free_propname;
    }

    if (set) {
    if (copy_from_user(propval, upropval, param.proplen)) {
    ret = -EFAULT;
    - goto out;
    + goto err_free_propval;
    }

    param.ret = fh_partition_set_dtprop(param.handle,
    @@ -392,7 +390,7 @@ static long ioctl_dtprop(struct fsl_hv_i
    if (copy_to_user(upropval, propval, param.proplen) ||
    put_user(param.proplen, &p->proplen)) {
    ret = -EFAULT;
    - goto out;
    + goto err_free_propval;
    }
    }
    }
    @@ -400,10 +398,12 @@ static long ioctl_dtprop(struct fsl_hv_i
    if (put_user(param.ret, &p->ret))
    ret = -EFAULT;

    -out:
    - kfree(path);
    +err_free_propval:
    kfree(propval);
    +err_free_propname:
    kfree(propname);
    +err_free_path:
    + kfree(path);

    return ret;
    }

    \
     
     \ /
      Last update: 2019-05-15 13:14    [W:4.054 / U:0.076 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site