Skip to content

Commit

Permalink
drm: mxsfb: Fix crash when provided invalid DT bindings
Browse files Browse the repository at this point in the history
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: Marek Vasut <[email protected]>
Cc: Daniel Vetter <[email protected]>
Cc: Dave Airlie <[email protected]>
Cc: Stefan Agner <[email protected]>
Cc: Breno Matheus Lima <[email protected]>
Tested-by: Breno Lima <[email protected]>
Signed-off-by: Dave Airlie <[email protected]>
  • Loading branch information
Marek Vasut authored and airlied committed Mar 10, 2017
1 parent 53990e4 commit 7ad7a5a
Showing 1 changed file with 4 additions and 0 deletions.
4 changes: 4 additions & 0 deletions drivers/gpu/drm/mxsfb/mxsfb_out.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ static int mxsfb_attach_endpoint(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 of_endpoint ep;
int ret;
Expand All @@ -127,5 +128,8 @@ int mxsfb_create_output(struct drm_device *drm)
}
}

if (!mxsfb->panel)
return -EPROBE_DEFER;

return 0;
}

0 comments on commit 7ad7a5a

Please sign in to comment.