HID: uhid: avoid dangling pointers in uhid context
authorDavid Herrmann <dh.herrmann@gmail.com>
Tue, 29 Jul 2014 15:14:17 +0000 (17:14 +0200)
committerJiri Kosina <jkosina@suse.cz>
Mon, 25 Aug 2014 08:28:06 +0000 (03:28 -0500)
Avoid keeping uhid->rd_data and uhid->rd_size set in case
uhid_dev_create2() fails. This is non-critical as we never flip
uhid->running and thus never enter uhid_dev_destroy(). However, it's much
nicer for debugging if pointers are only set if they point to valid data.

Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
drivers/hid/uhid.c

index c05b544cf588a11cb218aaa3a594170abcc67be8..bf13746d173154ed6e8d2dcc8ecc6ab0f4e6bb4b 100644 (file)
@@ -363,20 +363,24 @@ static int uhid_dev_create2(struct uhid_device *uhid,
                            const struct uhid_event *ev)
 {
        struct hid_device *hid;
+       size_t rd_size;
+       void *rd_data;
        int ret;
 
        if (uhid->running)
                return -EALREADY;
 
-       uhid->rd_size = ev->u.create2.rd_size;
-       if (uhid->rd_size <= 0 || uhid->rd_size > HID_MAX_DESCRIPTOR_SIZE)
+       rd_size = ev->u.create2.rd_size;
+       if (rd_size <= 0 || rd_size > HID_MAX_DESCRIPTOR_SIZE)
                return -EINVAL;
 
-       uhid->rd_data = kmemdup(ev->u.create2.rd_data, uhid->rd_size,
-                               GFP_KERNEL);
-       if (!uhid->rd_data)
+       rd_data = kmemdup(ev->u.create2.rd_data, rd_size, GFP_KERNEL);
+       if (!rd_data)
                return -ENOMEM;
 
+       uhid->rd_size = rd_size;
+       uhid->rd_data = rd_data;
+
        hid = hid_allocate_device();
        if (IS_ERR(hid)) {
                ret = PTR_ERR(hid);
@@ -416,6 +420,8 @@ err_hid:
        uhid->running = false;
 err_free:
        kfree(uhid->rd_data);
+       uhid->rd_data = NULL;
+       uhid->rd_size = 0;
        return ret;
 }