lkml.org 
[lkml]   [2016]   [Sep]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH 02/11] virtio_console: Less function calls in init_vqs() after error detection
    From
    Date
    From: Markus Elfring <elfring@users.sourceforge.net>
    Date: Wed, 14 Sep 2016 14:00:35 +0200

    The kfree() function was called in up to five cases
    by the init_vqs() function during error handling even if
    the passed variable contained a null pointer.

    * Return directly after a call of the function "kmalloc_array" failed
    at the beginning.

    * Split a condition check for memory allocation failures so that
    each pointer from these function calls will be checked immediately.

    See also background information:
    Topic "CWE-754: Improper check for unusual or exceptional conditions"
    Link: https://cwe.mitre.org/data/definitions/754.html

    * Adjust jump targets according to the Linux coding style convention.

    Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
    ---
    drivers/char/virtio_console.c | 32 ++++++++++++++++++++++++++------
    1 file changed, 26 insertions(+), 6 deletions(-)

    diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
    index 325ebc6..bf0ad57 100644
    --- a/drivers/char/virtio_console.c
    +++ b/drivers/char/virtio_console.c
    @@ -1882,20 +1882,37 @@ static int init_vqs(struct ports_device *portdev)
    nr_queues = use_multiport(portdev) ? (nr_ports + 1) * 2 : 2;

    vqs = kmalloc_array(nr_queues, sizeof(*vqs), GFP_KERNEL);
    + if (!vqs)
    + return -ENOMEM;
    +
    io_callbacks = kmalloc_array(nr_queues,
    sizeof(*io_callbacks),
    GFP_KERNEL);
    + if (!io_callbacks) {
    + err = -ENOMEM;
    + goto free_vqs;
    + }
    +
    io_names = kmalloc_array(nr_queues, sizeof(*io_names), GFP_KERNEL);
    + if (!io_names) {
    + err = -ENOMEM;
    + goto free_callbacks;
    + }
    +
    portdev->in_vqs = kmalloc_array(nr_ports,
    sizeof(*portdev->in_vqs),
    GFP_KERNEL);
    + if (!portdev->in_vqs) {
    + err = -ENOMEM;
    + goto free_names;
    + }
    +
    portdev->out_vqs = kmalloc_array(nr_ports,
    sizeof(*portdev->out_vqs),
    GFP_KERNEL);
    - if (!vqs || !io_callbacks || !io_names || !portdev->in_vqs ||
    - !portdev->out_vqs) {
    + if (!portdev->out_vqs) {
    err = -ENOMEM;
    - goto free;
    + goto free_in_vqs;
    }

    /*
    @@ -1929,7 +1946,7 @@ static int init_vqs(struct ports_device *portdev)
    io_callbacks,
    (const char **)io_names);
    if (err)
    - goto free;
    + goto free_out_vqs;

    j = 0;
    portdev->in_vqs[0] = vqs[0];
    @@ -1950,12 +1967,15 @@ static int init_vqs(struct ports_device *portdev)
    kfree(vqs);

    return 0;
    -
    -free:
    + free_out_vqs:
    kfree(portdev->out_vqs);
    + free_in_vqs:
    kfree(portdev->in_vqs);
    + free_names:
    kfree(io_names);
    + free_callbacks:
    kfree(io_callbacks);
    + free_vqs:
    kfree(vqs);

    return err;
    --
    2.10.0
    \
     
     \ /
      Last update: 2016-09-17 09:59    [W:4.019 / U:0.184 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site