lkml.org 
[lkml]   [2015]   [Jan]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.14 36/77] driver core: Fix unbalanced device reference in drivers_probe
    Date
    3.14-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Alex Williamson <alex.williamson@redhat.com>

    commit bb34cb6bbd287b57e955bc5cfd42fcde6aaca279 upstream.

    bus_find_device_by_name() acquires a device reference which is never
    released. This results in an object leak, which on older kernels
    results in failure to release all resources of PCI devices. libvirt
    uses drivers_probe to re-attach devices to the host after assignment
    and is therefore a common trigger for this leak.

    Example:

    # cd /sys/bus/pci/
    # dmesg -C
    # echo 1 > devices/0000\:01\:00.0/sriov_numvfs
    # echo 0 > devices/0000\:01\:00.0/sriov_numvfs
    # dmesg | grep 01:10
    pci 0000:01:10.0: [8086:10ca] type 00 class 0x020000
    kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_add_internal: parent: '0000:00:01.0', set: 'devices'
    kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_uevent_env
    kobject: '0000:01:10.0' (ffff8801d79cd0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0'
    kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_uevent_env
    kobject: '0000:01:10.0' (ffff8801d79cd0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0'
    kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_uevent_env
    kobject: '0000:01:10.0' (ffff8801d79cd0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0'
    kobject: '0000:01:10.0' (ffff8801d79cd0a8): kobject_cleanup, parent (null)
    kobject: '0000:01:10.0' (ffff8801d79cd0a8): calling ktype release
    kobject: '0000:01:10.0': free name

    [kobject freed as expected]

    # dmesg -C
    # echo 1 > devices/0000\:01\:00.0/sriov_numvfs
    # echo 0000:01:10.0 > drivers_probe
    # echo 0 > devices/0000\:01\:00.0/sriov_numvfs
    # dmesg | grep 01:10
    pci 0000:01:10.0: [8086:10ca] type 00 class 0x020000
    kobject: '0000:01:10.0' (ffff8801d79ce0a8): kobject_add_internal: parent: '0000:00:01.0', set: 'devices'
    kobject: '0000:01:10.0' (ffff8801d79ce0a8): kobject_uevent_env
    kobject: '0000:01:10.0' (ffff8801d79ce0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0'
    kobject: '0000:01:10.0' (ffff8801d79ce0a8): kobject_uevent_env
    kobject: '0000:01:10.0' (ffff8801d79ce0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0'
    kobject: '0000:01:10.0' (ffff8801d79ce0a8): kobject_uevent_env
    kobject: '0000:01:10.0' (ffff8801d79ce0a8): fill_kobj_path: path = '/devices/pci0000:00/0000:00:01.0/0000:01:10.0'

    [no free]

    Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/base/bus.c | 8 +++++---
    1 file changed, 5 insertions(+), 3 deletions(-)

    --- a/drivers/base/bus.c
    +++ b/drivers/base/bus.c
    @@ -254,13 +254,15 @@ static ssize_t store_drivers_probe(struc
    const char *buf, size_t count)
    {
    struct device *dev;
    + int err = -EINVAL;

    dev = bus_find_device_by_name(bus, NULL, buf);
    if (!dev)
    return -ENODEV;
    - if (bus_rescan_devices_helper(dev, NULL) != 0)
    - return -EINVAL;
    - return count;
    + if (bus_rescan_devices_helper(dev, NULL) == 0)
    + err = count;
    + put_device(dev);
    + return err;
    }

    static struct device *next_device(struct klist_iter *i)



    \
     
     \ /
      Last update: 2015-01-14 09:21    [W:4.845 / U:0.068 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site