All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/1] drm: modes: fix DRM modes analysis regression
@ 2015-12-09 13:30 LABBE Corentin
  2015-12-09 13:30 ` [PATCH v2 1/1] " LABBE Corentin
  0 siblings, 1 reply; 8+ messages in thread
From: LABBE Corentin @ 2015-12-09 13:30 UTC (permalink / raw)
  To: airlied; +Cc: LABBE Corentin, dri-devel, linux-kernel

Hello

Changes since v1
- Fix a memory leak when returning after an error of kstrtox

LABBE Corentin (1):
  drm: modes: fix DRM modes analysis regression

 drivers/gpu/drm/drm_modes.c | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

-- 
2.4.10


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/1] drm: modes: fix DRM modes analysis regression
  2015-12-09 13:30 [PATCH v2 0/1] drm: modes: fix DRM modes analysis regression LABBE Corentin
@ 2015-12-09 13:30 ` LABBE Corentin
  2015-12-09 15:32     ` Jani Nikula
  0 siblings, 1 reply; 8+ messages in thread
From: LABBE Corentin @ 2015-12-09 13:30 UTC (permalink / raw)
  To: airlied; +Cc: LABBE Corentin, dri-devel, linux-kernel

My latest commit introduce some case where a valid mode, could be
rejected.
simple_strtox functions stop at first non-digit character, but kstrtox not.
So args like "video=HDMI-A-1:720x480-16@60" will be reject when checking 16@.
The proper solution is to store digits in a specific buffer.

Fixes: 52157a4ca396 ("drm: modes: replace simple_strtoul by kstrtouint")
Reported-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: LABBE Corentin <clabbe.montjoie@gmail.com>
---
 drivers/gpu/drm/drm_modes.c | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index bde9b29..da1e80d 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -1225,13 +1225,14 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
 					       struct drm_cmdline_mode *mode)
 {
 	const char *name;
-	unsigned int namelen;
+	unsigned int namelen, digit_i;
 	bool res_specified = false, bpp_specified = false, refresh_specified = false;
 	unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0;
 	bool yres_specified = false, cvt = false, rb = false;
 	bool interlace = false, margins = false, was_digit = false;
 	int i, err;
 	enum drm_connector_force force = DRM_FORCE_UNSPECIFIED;
+	char *digits;
 
 #ifdef CONFIG_FB
 	if (!mode_option)
@@ -1245,42 +1246,53 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
 
 	name = mode_option;
 	namelen = strlen(name);
+
+	digits = kzalloc(namelen, GFP_KERNEL);
+	if (!digits)
+		return false;
+	/* The last character must be the last 0 */
+	digit_i = namelen;
+
 	for (i = namelen-1; i >= 0; i--) {
 		switch (name[i]) {
 		case '@':
 			if (!refresh_specified && !bpp_specified &&
 			    !yres_specified && !cvt && !rb && was_digit) {
-				err = kstrtouint(&name[i + 1], 10, &refresh);
+				err = kstrtouint(&digits[digit_i], 10, &refresh);
 				if (err)
-					return false;
+					goto done;
 				refresh_specified = true;
 				was_digit = false;
+				digit_i = namelen;
 			} else
 				goto done;
 			break;
 		case '-':
 			if (!bpp_specified && !yres_specified && !cvt &&
 			    !rb && was_digit) {
-				err = kstrtouint(&name[i + 1], 10, &bpp);
+				err = kstrtouint(&digits[digit_i], 10, &bpp);
 				if (err)
-					return false;
+					goto done;
 				bpp_specified = true;
 				was_digit = false;
+				digit_i = namelen;
 			} else
 				goto done;
 			break;
 		case 'x':
 			if (!yres_specified && was_digit) {
-				err = kstrtouint(&name[i + 1], 10, &yres);
+				err = kstrtouint(&digits[digit_i], 10, &yres);
 				if (err)
-					return false;
+					goto done;
 				yres_specified = true;
 				was_digit = false;
+				digit_i = namelen;
 			} else
 				goto done;
 			break;
 		case '0' ... '9':
 			was_digit = true;
+			digits[--digit_i] = name[i];
 			break;
 		case 'M':
 			if (yres_specified || cvt || was_digit)
@@ -1349,6 +1361,7 @@ done:
 			"parse error at position %i in video mode '%s'\n",
 			i, name);
 		mode->specified = false;
+		kfree(digits);
 		return false;
 	}
 
@@ -1373,6 +1386,7 @@ done:
 	mode->margins = margins;
 	mode->force = force;
 
+	kfree(digits);
 	return true;
 }
 EXPORT_SYMBOL(drm_mode_parse_command_line_for_connector);
-- 
2.4.10


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/1] drm: modes: fix DRM modes analysis regression
  2015-12-09 13:30 ` [PATCH v2 1/1] " LABBE Corentin
@ 2015-12-09 15:32     ` Jani Nikula
  0 siblings, 0 replies; 8+ messages in thread
From: Jani Nikula @ 2015-12-09 15:32 UTC (permalink / raw)
  To: LABBE Corentin, airlied; +Cc: LABBE Corentin, linux-kernel, dri-devel

On Wed, 09 Dec 2015, LABBE Corentin <clabbe.montjoie@gmail.com> wrote:
> My latest commit introduce some case where a valid mode, could be
> rejected.
> simple_strtox functions stop at first non-digit character, but kstrtox not.
> So args like "video=HDMI-A-1:720x480-16@60" will be reject when checking 16@.
> The proper solution is to store digits in a specific buffer.

Or to revert regressing commit...? Your original commit complicated the
already complicated function, and this one makes it more so. What is the
benefit?

> Fixes: 52157a4ca396 ("drm: modes: replace simple_strtoul by kstrtouint")

For me the commit id is cc344980c76748e57c9c03100c2a14d36ab00334.

BR,
Jani.

> Reported-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> Signed-off-by: LABBE Corentin <clabbe.montjoie@gmail.com>
> ---
>  drivers/gpu/drm/drm_modes.c | 28 +++++++++++++++++++++-------
>  1 file changed, 21 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> index bde9b29..da1e80d 100644
> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -1225,13 +1225,14 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
>  					       struct drm_cmdline_mode *mode)
>  {
>  	const char *name;
> -	unsigned int namelen;
> +	unsigned int namelen, digit_i;
>  	bool res_specified = false, bpp_specified = false, refresh_specified = false;
>  	unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0;
>  	bool yres_specified = false, cvt = false, rb = false;
>  	bool interlace = false, margins = false, was_digit = false;
>  	int i, err;
>  	enum drm_connector_force force = DRM_FORCE_UNSPECIFIED;
> +	char *digits;
>  
>  #ifdef CONFIG_FB
>  	if (!mode_option)
> @@ -1245,42 +1246,53 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
>  
>  	name = mode_option;
>  	namelen = strlen(name);
> +
> +	digits = kzalloc(namelen, GFP_KERNEL);
> +	if (!digits)
> +		return false;
> +	/* The last character must be the last 0 */
> +	digit_i = namelen;
> +
>  	for (i = namelen-1; i >= 0; i--) {
>  		switch (name[i]) {
>  		case '@':
>  			if (!refresh_specified && !bpp_specified &&
>  			    !yres_specified && !cvt && !rb && was_digit) {
> -				err = kstrtouint(&name[i + 1], 10, &refresh);
> +				err = kstrtouint(&digits[digit_i], 10, &refresh);
>  				if (err)
> -					return false;
> +					goto done;
>  				refresh_specified = true;
>  				was_digit = false;
> +				digit_i = namelen;
>  			} else
>  				goto done;
>  			break;
>  		case '-':
>  			if (!bpp_specified && !yres_specified && !cvt &&
>  			    !rb && was_digit) {
> -				err = kstrtouint(&name[i + 1], 10, &bpp);
> +				err = kstrtouint(&digits[digit_i], 10, &bpp);
>  				if (err)
> -					return false;
> +					goto done;
>  				bpp_specified = true;
>  				was_digit = false;
> +				digit_i = namelen;
>  			} else
>  				goto done;
>  			break;
>  		case 'x':
>  			if (!yres_specified && was_digit) {
> -				err = kstrtouint(&name[i + 1], 10, &yres);
> +				err = kstrtouint(&digits[digit_i], 10, &yres);
>  				if (err)
> -					return false;
> +					goto done;
>  				yres_specified = true;
>  				was_digit = false;
> +				digit_i = namelen;
>  			} else
>  				goto done;
>  			break;
>  		case '0' ... '9':
>  			was_digit = true;
> +			digits[--digit_i] = name[i];
>  			break;
>  		case 'M':
>  			if (yres_specified || cvt || was_digit)
> @@ -1349,6 +1361,7 @@ done:
>  			"parse error at position %i in video mode '%s'\n",
>  			i, name);
>  		mode->specified = false;
> +		kfree(digits);
>  		return false;
>  	}
>  
> @@ -1373,6 +1386,7 @@ done:
>  	mode->margins = margins;
>  	mode->force = force;
>  
> +	kfree(digits);
>  	return true;
>  }
>  EXPORT_SYMBOL(drm_mode_parse_command_line_for_connector);

-- 
Jani Nikula, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/1] drm: modes: fix DRM modes analysis regression
@ 2015-12-09 15:32     ` Jani Nikula
  0 siblings, 0 replies; 8+ messages in thread
From: Jani Nikula @ 2015-12-09 15:32 UTC (permalink / raw)
  To: airlied; +Cc: LABBE Corentin, linux-kernel, dri-devel

On Wed, 09 Dec 2015, LABBE Corentin <clabbe.montjoie@gmail.com> wrote:
> My latest commit introduce some case where a valid mode, could be
> rejected.
> simple_strtox functions stop at first non-digit character, but kstrtox not.
> So args like "video=HDMI-A-1:720x480-16@60" will be reject when checking 16@.
> The proper solution is to store digits in a specific buffer.

Or to revert regressing commit...? Your original commit complicated the
already complicated function, and this one makes it more so. What is the
benefit?

> Fixes: 52157a4ca396 ("drm: modes: replace simple_strtoul by kstrtouint")

For me the commit id is cc344980c76748e57c9c03100c2a14d36ab00334.

BR,
Jani.

> Reported-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> Signed-off-by: LABBE Corentin <clabbe.montjoie@gmail.com>
> ---
>  drivers/gpu/drm/drm_modes.c | 28 +++++++++++++++++++++-------
>  1 file changed, 21 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> index bde9b29..da1e80d 100644
> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -1225,13 +1225,14 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
>  					       struct drm_cmdline_mode *mode)
>  {
>  	const char *name;
> -	unsigned int namelen;
> +	unsigned int namelen, digit_i;
>  	bool res_specified = false, bpp_specified = false, refresh_specified = false;
>  	unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0;
>  	bool yres_specified = false, cvt = false, rb = false;
>  	bool interlace = false, margins = false, was_digit = false;
>  	int i, err;
>  	enum drm_connector_force force = DRM_FORCE_UNSPECIFIED;
> +	char *digits;
>  
>  #ifdef CONFIG_FB
>  	if (!mode_option)
> @@ -1245,42 +1246,53 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
>  
>  	name = mode_option;
>  	namelen = strlen(name);
> +
> +	digits = kzalloc(namelen, GFP_KERNEL);
> +	if (!digits)
> +		return false;
> +	/* The last character must be the last 0 */
> +	digit_i = namelen;
> +
>  	for (i = namelen-1; i >= 0; i--) {
>  		switch (name[i]) {
>  		case '@':
>  			if (!refresh_specified && !bpp_specified &&
>  			    !yres_specified && !cvt && !rb && was_digit) {
> -				err = kstrtouint(&name[i + 1], 10, &refresh);
> +				err = kstrtouint(&digits[digit_i], 10, &refresh);
>  				if (err)
> -					return false;
> +					goto done;
>  				refresh_specified = true;
>  				was_digit = false;
> +				digit_i = namelen;
>  			} else
>  				goto done;
>  			break;
>  		case '-':
>  			if (!bpp_specified && !yres_specified && !cvt &&
>  			    !rb && was_digit) {
> -				err = kstrtouint(&name[i + 1], 10, &bpp);
> +				err = kstrtouint(&digits[digit_i], 10, &bpp);
>  				if (err)
> -					return false;
> +					goto done;
>  				bpp_specified = true;
>  				was_digit = false;
> +				digit_i = namelen;
>  			} else
>  				goto done;
>  			break;
>  		case 'x':
>  			if (!yres_specified && was_digit) {
> -				err = kstrtouint(&name[i + 1], 10, &yres);
> +				err = kstrtouint(&digits[digit_i], 10, &yres);
>  				if (err)
> -					return false;
> +					goto done;
>  				yres_specified = true;
>  				was_digit = false;
> +				digit_i = namelen;
>  			} else
>  				goto done;
>  			break;
>  		case '0' ... '9':
>  			was_digit = true;
> +			digits[--digit_i] = name[i];
>  			break;
>  		case 'M':
>  			if (yres_specified || cvt || was_digit)
> @@ -1349,6 +1361,7 @@ done:
>  			"parse error at position %i in video mode '%s'\n",
>  			i, name);
>  		mode->specified = false;
> +		kfree(digits);
>  		return false;
>  	}
>  
> @@ -1373,6 +1386,7 @@ done:
>  	mode->margins = margins;
>  	mode->force = force;
>  
> +	kfree(digits);
>  	return true;
>  }
>  EXPORT_SYMBOL(drm_mode_parse_command_line_for_connector);

-- 
Jani Nikula, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/1] drm: modes: fix DRM modes analysis regression
  2015-12-09 15:32     ` Jani Nikula
@ 2015-12-09 19:11       ` Corentin LABBE
  -1 siblings, 0 replies; 8+ messages in thread
From: Corentin LABBE @ 2015-12-09 19:11 UTC (permalink / raw)
  To: Jani Nikula, airlied; +Cc: linux-kernel, dri-devel

Le 09/12/2015 16:32, Jani Nikula a écrit :
> On Wed, 09 Dec 2015, LABBE Corentin <clabbe.montjoie@gmail.com> wrote:
>> My latest commit introduce some case where a valid mode, could be
>> rejected.
>> simple_strtox functions stop at first non-digit character, but kstrtox not.
>> So args like "video=HDMI-A-1:720x480-16@60" will be reject when checking 16@.
>> The proper solution is to store digits in a specific buffer.
> 
> Or to revert regressing commit...? Your original commit complicated the
> already complicated function, and this one makes it more so. What is the
> benefit?
> 

The benefit is to remove a function marked obsolete who do not said if the conversation is successful or not.
But I understand that the way I have done it was not the best one.
If the maintainer want it, I will send a patch for reverting the first patch.

>> Fixes: 52157a4ca396 ("drm: modes: replace simple_strtoul by kstrtouint")
> 
> For me the commit id is cc344980c76748e57c9c03100c2a14d36ab00334.

Oups, I took commit id from my local git.

Regards


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/1] drm: modes: fix DRM modes analysis regression
@ 2015-12-09 19:11       ` Corentin LABBE
  0 siblings, 0 replies; 8+ messages in thread
From: Corentin LABBE @ 2015-12-09 19:11 UTC (permalink / raw)
  To: Jani Nikula, airlied; +Cc: linux-kernel, dri-devel

Le 09/12/2015 16:32, Jani Nikula a écrit :
> On Wed, 09 Dec 2015, LABBE Corentin <clabbe.montjoie@gmail.com> wrote:
>> My latest commit introduce some case where a valid mode, could be
>> rejected.
>> simple_strtox functions stop at first non-digit character, but kstrtox not.
>> So args like "video=HDMI-A-1:720x480-16@60" will be reject when checking 16@.
>> The proper solution is to store digits in a specific buffer.
> 
> Or to revert regressing commit...? Your original commit complicated the
> already complicated function, and this one makes it more so. What is the
> benefit?
> 

The benefit is to remove a function marked obsolete who do not said if the conversation is successful or not.
But I understand that the way I have done it was not the best one.
If the maintainer want it, I will send a patch for reverting the first patch.

>> Fixes: 52157a4ca396 ("drm: modes: replace simple_strtoul by kstrtouint")
> 
> For me the commit id is cc344980c76748e57c9c03100c2a14d36ab00334.

Oups, I took commit id from my local git.

Regards

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/1] drm: modes: fix DRM modes analysis regression
  2015-12-09 19:11       ` Corentin LABBE
@ 2015-12-10  8:04         ` Daniel Vetter
  -1 siblings, 0 replies; 8+ messages in thread
From: Daniel Vetter @ 2015-12-10  8:04 UTC (permalink / raw)
  To: Corentin LABBE; +Cc: Jani Nikula, airlied, linux-kernel, dri-devel

On Wed, Dec 09, 2015 at 08:11:39PM +0100, Corentin LABBE wrote:
> Le 09/12/2015 16:32, Jani Nikula a écrit :
> > On Wed, 09 Dec 2015, LABBE Corentin <clabbe.montjoie@gmail.com> wrote:
> >> My latest commit introduce some case where a valid mode, could be
> >> rejected.
> >> simple_strtox functions stop at first non-digit character, but kstrtox not.
> >> So args like "video=HDMI-A-1:720x480-16@60" will be reject when checking 16@.
> >> The proper solution is to store digits in a specific buffer.
> > 
> > Or to revert regressing commit...? Your original commit complicated the
> > already complicated function, and this one makes it more so. What is the
> > benefit?
> > 
> 
> The benefit is to remove a function marked obsolete who do not said if the conversation is successful or not.
> But I understand that the way I have done it was not the best one.
> If the maintainer want it, I will send a patch for reverting the first patch.

Given that nothin bad happens if we misparse the number (black screen) and
there's no screen resolution even close to the limit of what can be
parsed, I think reverting is the right action.

Carefully parsing userspace input makes sense. But this is the kernel
cmdline, if your attacker can change that you've lost no matter what.

Please send in the revert with a short summary of the discussion here.

Thanks, Daniel

> 
> >> Fixes: 52157a4ca396 ("drm: modes: replace simple_strtoul by kstrtouint")
> > 
> > For me the commit id is cc344980c76748e57c9c03100c2a14d36ab00334.
> 
> Oups, I took commit id from my local git.
> 
> Regards
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/1] drm: modes: fix DRM modes analysis regression
@ 2015-12-10  8:04         ` Daniel Vetter
  0 siblings, 0 replies; 8+ messages in thread
From: Daniel Vetter @ 2015-12-10  8:04 UTC (permalink / raw)
  To: Corentin LABBE; +Cc: dri-devel, linux-kernel

On Wed, Dec 09, 2015 at 08:11:39PM +0100, Corentin LABBE wrote:
> Le 09/12/2015 16:32, Jani Nikula a écrit :
> > On Wed, 09 Dec 2015, LABBE Corentin <clabbe.montjoie@gmail.com> wrote:
> >> My latest commit introduce some case where a valid mode, could be
> >> rejected.
> >> simple_strtox functions stop at first non-digit character, but kstrtox not.
> >> So args like "video=HDMI-A-1:720x480-16@60" will be reject when checking 16@.
> >> The proper solution is to store digits in a specific buffer.
> > 
> > Or to revert regressing commit...? Your original commit complicated the
> > already complicated function, and this one makes it more so. What is the
> > benefit?
> > 
> 
> The benefit is to remove a function marked obsolete who do not said if the conversation is successful or not.
> But I understand that the way I have done it was not the best one.
> If the maintainer want it, I will send a patch for reverting the first patch.

Given that nothin bad happens if we misparse the number (black screen) and
there's no screen resolution even close to the limit of what can be
parsed, I think reverting is the right action.

Carefully parsing userspace input makes sense. But this is the kernel
cmdline, if your attacker can change that you've lost no matter what.

Please send in the revert with a short summary of the discussion here.

Thanks, Daniel

> 
> >> Fixes: 52157a4ca396 ("drm: modes: replace simple_strtoul by kstrtouint")
> > 
> > For me the commit id is cc344980c76748e57c9c03100c2a14d36ab00334.
> 
> Oups, I took commit id from my local git.
> 
> Regards
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-12-10  8:04 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-09 13:30 [PATCH v2 0/1] drm: modes: fix DRM modes analysis regression LABBE Corentin
2015-12-09 13:30 ` [PATCH v2 1/1] " LABBE Corentin
2015-12-09 15:32   ` Jani Nikula
2015-12-09 15:32     ` Jani Nikula
2015-12-09 19:11     ` Corentin LABBE
2015-12-09 19:11       ` Corentin LABBE
2015-12-10  8:04       ` Daniel Vetter
2015-12-10  8:04         ` Daniel Vetter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.