dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Chris Wilson <chris@chris-wilson.co.uk>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH] drm: Prevent use of uninitialised values whilst loading edid firmware
Date: Tue, 1 Oct 2013 18:49:42 +0300	[thread overview]
Message-ID: <20131001154942.GN9395@intel.com> (raw)
In-Reply-To: <1380632773-15183-1-git-send-email-chris@chris-wilson.co.uk>

On Tue, Oct 01, 2013 at 02:06:13PM +0100, Chris Wilson wrote:
>  CC      drivers/gpu/drm/drm_edid_load.o
> drivers/gpu/drm/drm_edid_load.c: In function ‘drm_load_edid_firmware’: include/linux/err.h:39:17: warning: ‘edid’ may be used uninitialised in this function [-Wuninitialized]
> drivers/gpu/drm/drm_edid_load.c:141:22: note: ‘edid’ was declared here
> 
> In the process, we can make the error handling more resilient.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>  drivers/gpu/drm/drm_edid_load.c |   75 +++++++++++++++++----------------------
>  1 file changed, 32 insertions(+), 43 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c
> index 271b42b..4b57a4c 100644
> --- a/drivers/gpu/drm/drm_edid_load.c
> +++ b/drivers/gpu/drm/drm_edid_load.c
> @@ -136,59 +136,51 @@ static u8 generic_edid[GENERIC_EDIDS][128] = {
>  static u8 *edid_load(struct drm_connector *connector, const char *name,
>  			const char *connector_name)
>  {
> -	const struct firmware *fw;
> +	const struct firmware *fw = NULL;
>  	struct platform_device *pdev;
> -	u8 *fwdata = NULL, *edid, *new_edid;
> -	int fwsize, expected;
> -	int builtin = 0, err = 0;
> +	u8 *fwdata, *edid;

Orthogonal issue, but fwdata, generic_edid and generic_edid_names could
all be const.

> +	int fwsize, expected, err, builtin;
>  	int i, valid_extensions = 0;
>  	bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS);
>  
>  	pdev = platform_device_register_simple(connector_name, -1, NULL, 0);
> -	if (IS_ERR(pdev)) {
> -		DRM_ERROR("Failed to register EDID firmware platform device "
> -		    "for connector \"%s\"\n", connector_name);
> -		err = -EINVAL;
> -		goto out;
> -	}
> -
> -	err = request_firmware(&fw, name, &pdev->dev);
> -	platform_device_unregister(pdev);
> +	if (!IS_ERR(pdev)) {
> +		err = request_firmware(&fw, name, &pdev->dev);
> +		platform_device_unregister(pdev);
> +	} else
> +		err = PTR_ERR(pdev);
>  
> -	if (err) {
> +	if (err == 0) {
> +		fwdata = (u8 *)fw->data;
> +		fwsize = fw->size;
> +		builtin = 0;
> +	} else {
>  		i = 0;
>  		while (i < GENERIC_EDIDS && strcmp(name, generic_edid_name[i]))
>  			i++;
> -		if (i < GENERIC_EDIDS) {
> -			err = 0;
> -			builtin = 1;
> -			fwdata = generic_edid[i];
> -			fwsize = sizeof(generic_edid[i]);
> +		if (i >= GENERIC_EDIDS) {
> +			DRM_ERROR("Requesting EDID firmware \"%s\" failed (err=%d)\n",
> +					name, err);
> +			edid = ERR_PTR(err);
> +			goto out;

Due to the 'if (fw)' check in the cleanup code, you could eliminate
the out label.

>  		}
> -	}
>  
> -	if (err) {
> -		DRM_ERROR("Requesting EDID firmware \"%s\" failed (err=%d)\n",
> -		    name, err);
> -		goto out;
> -	}
> -
> -	if (fwdata == NULL) {
> -		fwdata = (u8 *) fw->data;
> -		fwsize = fw->size;
> +		fwdata = generic_edid[i];
> +		fwsize = sizeof(generic_edid[i]);
> +		builtin = 1;
>  	}
>  
>  	expected = (fwdata[0x7e] + 1) * EDID_LENGTH;

Not your bug, but we're missing a check for fwsize > 0x7e.

Can't spot any real bugs, so w/ or w/o the out label idea:
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

>  	if (expected != fwsize) {
>  		DRM_ERROR("Size of EDID firmware \"%s\" is invalid "
>  		    "(expected %d, got %d)\n", name, expected, (int) fwsize);
> -		err = -EINVAL;
> +		edid = ERR_PTR(-EINVAL);
>  		goto relfw_out;
>  	}
>  
>  	edid = kmemdup(fwdata, fwsize, GFP_KERNEL);
>  	if (edid == NULL) {
> -		err = -ENOMEM;
> +		edid = ERR_PTR(-ENOMEM);
>  		goto relfw_out;
>  	}
>  
> @@ -197,7 +189,7 @@ static u8 *edid_load(struct drm_connector *connector, const char *name,
>  		DRM_ERROR("Base block of EDID firmware \"%s\" is invalid ",
>  		    name);
>  		kfree(edid);
> -		err = -EINVAL;
> +		edid = ERR_PTR(-EINVAL);
>  		goto relfw_out;
>  	}
>  
> @@ -210,19 +202,18 @@ static u8 *edid_load(struct drm_connector *connector, const char *name,
>  	}
>  
>  	if (valid_extensions != edid[0x7e]) {
> +		u8 *new_edid;
> +
>  		edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
>  		DRM_INFO("Found %d valid extensions instead of %d in EDID data "
>  		    "\"%s\" for connector \"%s\"\n", valid_extensions,
>  		    edid[0x7e], name, connector_name);
>  		edid[0x7e] = valid_extensions;
> +
>  		new_edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH,
> -		    GFP_KERNEL);
> -		if (new_edid == NULL) {
> -			err = -ENOMEM;
> -			kfree(edid);
> -			goto relfw_out;
> -		}
> -		edid = new_edid;
> +				    GFP_KERNEL);
> +		if (new_edid)
> +			edid = new_edid;
>  	}
>  
>  	DRM_INFO("Got %s EDID base block and %d extension%s from "
> @@ -231,12 +222,10 @@ static u8 *edid_load(struct drm_connector *connector, const char *name,
>  	    name, connector_name);
>  
>  relfw_out:
> -	release_firmware(fw);
> +	if (fw)
> +		release_firmware(fw);
>  
>  out:
> -	if (err)
> -		return ERR_PTR(err);
> -
>  	return edid;
>  }
>  
> -- 
> 1.7.9.5
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2013-10-01 15:49 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-01 13:06 [PATCH] drm: Prevent use of uninitialised values whilst loading edid firmware Chris Wilson
2013-10-01 15:49 ` Ville Syrjälä [this message]
2013-10-01 16:22   ` Chris Wilson
2013-10-02  7:52     ` Jani Nikula
2013-10-02  9:07       ` [PATCH] drm: Try loading builtin EDIDs first Chris Wilson
2013-10-02  9:22         ` Ville Syrjälä
2013-10-02  9:32           ` Chris Wilson
2013-10-02  9:56             ` Ville Syrjälä
2013-10-02 10:12               ` Chris Wilson
2013-10-02 11:12                 ` Jani Nikula

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20131001154942.GN9395@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=chris@chris-wilson.co.uk \
    --cc=dri-devel@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).