]>
Commit | Line | Data |
---|---|---|
9d09275e GKH |
1 | From fcb74da1eb8edd3a4ef9b9724f88ed709d684227 Mon Sep 17 00:00:00 2001 |
2 | From: Emil Lundmark <lndmrk@chromium.org> | |
3 | Date: Mon, 28 May 2018 16:27:11 +0200 | |
4 | Subject: drm: udl: Destroy framebuffer only if it was initialized | |
5 | MIME-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ||
9 | From: Emil Lundmark <lndmrk@chromium.org> | |
10 | ||
11 | commit fcb74da1eb8edd3a4ef9b9724f88ed709d684227 upstream. | |
12 | ||
13 | This fixes a NULL pointer dereference that can happen if the UDL | |
14 | driver is unloaded before the framebuffer is initialized. This can | |
15 | happen e.g. if the USB device is unplugged right after it was plugged | |
16 | in. | |
17 | ||
18 | As explained by Stéphane Marchesin: | |
19 | ||
20 | It happens when fbdev is disabled (which is the case for Chrome OS). | |
21 | Even though intialization of the fbdev part is optional (it's done in | |
22 | udlfb_create which is the callback for fb_probe()), the teardown isn't | |
23 | optional (udl_driver_unload -> udl_fbdev_cleanup -> | |
24 | udl_fbdev_destroy). | |
25 | ||
26 | Note that udl_fbdev_cleanup *tries* to be conditional (you can see it | |
27 | does if (!udl->fbdev)) but that doesn't work, because udl->fbdev is | |
28 | always set during udl_fbdev_init. | |
29 | ||
30 | Cc: stable@vger.kernel.org | |
31 | Suggested-by: Sean Paul <seanpaul@chromium.org> | |
32 | Reviewed-by: Sean Paul <seanpaul@chromium.org> | |
33 | Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> | |
34 | Signed-off-by: Emil Lundmark <lndmrk@chromium.org> | |
35 | Signed-off-by: Sean Paul <seanpaul@chromium.org> | |
36 | Link: https://patchwork.freedesktop.org/patch/msgid/20180528142711.142466-1-lndmrk@chromium.org | |
37 | Signed-off-by: Sean Paul <seanpaul@chromium.org> | |
38 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
39 | ||
40 | --- | |
41 | drivers/gpu/drm/udl/udl_fb.c | 8 +++++--- | |
42 | 1 file changed, 5 insertions(+), 3 deletions(-) | |
43 | ||
44 | --- a/drivers/gpu/drm/udl/udl_fb.c | |
45 | +++ b/drivers/gpu/drm/udl/udl_fb.c | |
46 | @@ -432,9 +432,11 @@ static void udl_fbdev_destroy(struct drm | |
47 | { | |
48 | drm_fb_helper_unregister_fbi(&ufbdev->helper); | |
49 | drm_fb_helper_fini(&ufbdev->helper); | |
50 | - drm_framebuffer_unregister_private(&ufbdev->ufb.base); | |
51 | - drm_framebuffer_cleanup(&ufbdev->ufb.base); | |
52 | - drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base); | |
53 | + if (ufbdev->ufb.obj) { | |
54 | + drm_framebuffer_unregister_private(&ufbdev->ufb.base); | |
55 | + drm_framebuffer_cleanup(&ufbdev->ufb.base); | |
56 | + drm_gem_object_put_unlocked(&ufbdev->ufb.obj->base); | |
57 | + } | |
58 | } | |
59 | ||
60 | int udl_fbdev_init(struct drm_device *dev) |