Commit 7ad7a5ac authored by Marek Vasut's avatar Marek Vasut Committed by Dave Airlie

drm: mxsfb: Fix crash when provided invalid DT bindings

The mxsfb driver will crash if the mxsfb DT node has a subnode,
but the content of the subnode is not of-graph binding with an
endpoint linking to panel. The crash was triggered by providing
old-style panel bindings to the mxsfb driver instead of the new
of-graph ones.

The problem happens in mxsfb_create_output(), which is invoked
from mxsfb_load(). The mxsfb_create_output() iterates over all
mxsfb DT subnode endpoints and tries to bind a panel on each
endpoint. If there is any problem binding the panel, that is,
mxsfb->panel == NULL, this function will return an error code,
otherwise success 0 is returned.

If the subnodes do not specify of-graph binding with an endpoint,
the iteration over endpoints in mxsfb_create_output() will have
zero cycles and the function will immediatelly return 0, but the
mxsfb->panel will remain NULL. This is propagated back into the
mxsfb_load(), which does not detect any problem and expects that
the mxsfb->panel is valid, thus calls mxsfb_panel_attach(). But
since mxsfb->panel == NULL, mxsfb_panel_attach() is called with
first argument NULL and this crashes the kernel.

This patch fixes the problem by explicitly checking for valid
mxsfb->panel at the end of the iteration in mxsfb_create_output().
Signed-off-by: default avatarMarek Vasut <marex@denx.de>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Breno Matheus Lima <brenomatheus@gmail.com>
Tested-by: default avatarBreno Lima <breno.lima@nxp.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 53990e41
...@@ -112,6 +112,7 @@ static int mxsfb_attach_endpoint(struct drm_device *drm, ...@@ -112,6 +112,7 @@ static int mxsfb_attach_endpoint(struct drm_device *drm,
int mxsfb_create_output(struct drm_device *drm) int mxsfb_create_output(struct drm_device *drm)
{ {
struct mxsfb_drm_private *mxsfb = drm->dev_private;
struct device_node *ep_np = NULL; struct device_node *ep_np = NULL;
struct of_endpoint ep; struct of_endpoint ep;
int ret; int ret;
...@@ -127,5 +128,8 @@ int mxsfb_create_output(struct drm_device *drm) ...@@ -127,5 +128,8 @@ int mxsfb_create_output(struct drm_device *drm)
} }
} }
if (!mxsfb->panel)
return -EPROBE_DEFER;
return 0; return 0;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment