drm/nouveau: fix edid memleak in nouveau_connector
authorXavier Chantry <shiningxc@gmail.com>
Mon, 11 Jan 2010 21:42:21 +0000 (22:42 +0100)
committerBen Skeggs <bskeggs@redhat.com>
Thu, 14 Jan 2010 23:28:48 +0000 (09:28 +1000)
This was spotted by kmemleak.

Signed-off-by: Xavier Chantry <shiningxc@gmail.com>
Signed-off-by: Francisco Jerez <currojerez@riseup.net>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_connector.c

index 5a10deb..54c8530 100644 (file)
@@ -83,14 +83,16 @@ nouveau_encoder_connector_get(struct nouveau_encoder *encoder)
 static void
 nouveau_connector_destroy(struct drm_connector *drm_connector)
 {
-       struct nouveau_connector *connector = nouveau_connector(drm_connector);
-       struct drm_device *dev = connector->base.dev;
+       struct nouveau_connector *nv_connector =
+               nouveau_connector(drm_connector);
+       struct drm_device *dev = nv_connector->base.dev;
 
        NV_DEBUG_KMS(dev, "\n");
 
-       if (!connector)
+       if (!nv_connector)
                return;
 
+       kfree(nv_connector->edid);
        drm_sysfs_connector_remove(drm_connector);
        drm_connector_cleanup(drm_connector);
        kfree(drm_connector);
@@ -237,6 +239,9 @@ nouveau_connector_detect(struct drm_connector *connector)
                return connector_status_connected;
        }
 
+       kfree(nv_connector->edid);
+       nv_connector->edid = NULL;
+
        i2c = nouveau_connector_ddc_detect(connector, &nv_encoder);
        if (i2c) {
                nouveau_connector_ddc_prepare(connector, &flags);
@@ -687,8 +692,12 @@ nouveau_connector_create_lvds(struct drm_device *dev,
         */
        if (!nv_connector->edid && !nv_connector->native_mode &&
            !dev_priv->VBIOS.pub.fp_no_ddc) {
-               nv_connector->edid =
+               struct edid *edid =
                        (struct edid *)nouveau_bios_embedded_edid(dev);
+               if (edid) {
+                       nv_connector->edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+                       *(nv_connector->edid) = *edid;
+               }
        }
 
        if (!nv_connector->edid)