| From cac5fcedaabdadf150c8a9be9fee76defc8ba444 Mon Sep 17 00:00:00 2001 |
| From: Felix Monninger <felix.monninger@gmail.com> |
| Date: Tue, 25 Oct 2016 22:28:08 +0100 |
| Subject: drm: Release reference from blob lookup after replacing property |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Felix Monninger <felix.monninger@gmail.com> |
| |
| commit cac5fcedaabdadf150c8a9be9fee76defc8ba444 upstream. |
| |
| drm_property_lookup_blob() returns a reference to the returned blob, and |
| drm_atomic_replace_property_blob() takes a references to the blob it |
| stores, so afterwards we are left owning a reference to the new_blob that |
| we never release, and thus leak memory every time we update a property |
| such as during drm_atomic_helper_legacy_gamma_set(). |
| |
| v2: update credentials, drm_property_unreference_blob() is NULL safe and |
| NULL is passed consistently to it throughout drm_atomic.c so do so here. |
| |
| Reported-by: Felix Monninger <felix.monninger@gmail.com> |
| Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98420 |
| Signed-off-by: Felix Monninger <felix.monninger@gmail.com> |
| Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> |
| Fixes: 5488dc16fde7 ("drm: introduce pipe color correction properties") |
| Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> |
| Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> |
| Link: http://patchwork.freedesktop.org/patch/msgid/20161025212808.3908-1-chris@chris-wilson.co.uk |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/gpu/drm/drm_atomic.c | 9 ++++++--- |
| 1 file changed, 6 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/gpu/drm/drm_atomic.c |
| +++ b/drivers/gpu/drm/drm_atomic.c |
| @@ -420,18 +420,21 @@ drm_atomic_replace_property_blob_from_id |
| ssize_t expected_size, |
| bool *replaced) |
| { |
| - struct drm_device *dev = crtc->dev; |
| struct drm_property_blob *new_blob = NULL; |
| |
| if (blob_id != 0) { |
| - new_blob = drm_property_lookup_blob(dev, blob_id); |
| + new_blob = drm_property_lookup_blob(crtc->dev, blob_id); |
| if (new_blob == NULL) |
| return -EINVAL; |
| - if (expected_size > 0 && expected_size != new_blob->length) |
| + |
| + if (expected_size > 0 && expected_size != new_blob->length) { |
| + drm_property_unreference_blob(new_blob); |
| return -EINVAL; |
| + } |
| } |
| |
| drm_atomic_replace_property_blob(blob, new_blob, replaced); |
| + drm_property_unreference_blob(new_blob); |
| |
| return 0; |
| } |