diff options
author | Felix Monninger <felix.monninger@gmail.com> | 2016-10-25 17:28:08 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-10-26 04:28:10 -0400 |
commit | cac5fcedaabdadf150c8a9be9fee76defc8ba444 (patch) | |
tree | baede9f453be91b7c875ea4589b13c80a622bcb2 | |
parent | 07d9a380680d1c0eb51ef87ff2eab5c994949e69 (diff) |
drm: Release reference from blob lookup after replacing property
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>
Cc: stable@vger.kernel.org
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
-rw-r--r-- | drivers/gpu/drm/drm_atomic.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 23739609427d..e6862a744210 100644 --- 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(struct drm_crtc *crtc, | |||
420 | ssize_t expected_size, | 420 | ssize_t expected_size, |
421 | bool *replaced) | 421 | bool *replaced) |
422 | { | 422 | { |
423 | struct drm_device *dev = crtc->dev; | ||
424 | struct drm_property_blob *new_blob = NULL; | 423 | struct drm_property_blob *new_blob = NULL; |
425 | 424 | ||
426 | if (blob_id != 0) { | 425 | if (blob_id != 0) { |
427 | new_blob = drm_property_lookup_blob(dev, blob_id); | 426 | new_blob = drm_property_lookup_blob(crtc->dev, blob_id); |
428 | if (new_blob == NULL) | 427 | if (new_blob == NULL) |
429 | return -EINVAL; | 428 | return -EINVAL; |
430 | if (expected_size > 0 && expected_size != new_blob->length) | 429 | |
430 | if (expected_size > 0 && expected_size != new_blob->length) { | ||
431 | drm_property_unreference_blob(new_blob); | ||
431 | return -EINVAL; | 432 | return -EINVAL; |
433 | } | ||
432 | } | 434 | } |
433 | 435 | ||
434 | drm_atomic_replace_property_blob(blob, new_blob, replaced); | 436 | drm_atomic_replace_property_blob(blob, new_blob, replaced); |
437 | drm_property_unreference_blob(new_blob); | ||
435 | 438 | ||
436 | return 0; | 439 | return 0; |
437 | } | 440 | } |