public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] leds: trigger: ledtrig-backlight: Fix invalid memory access in fb_event notification callback
@ 2013-08-13 11:17 Manfred Schlaegl
  2013-08-27  0:51 ` Bryan Wu
  0 siblings, 1 reply; 3+ messages in thread
From: Manfred Schlaegl @ 2013-08-13 11:17 UTC (permalink / raw)
  To: Bryan Wu, Richard Purdie, Jingoo Han, Milo(Woogyom) Kim,
	Sachin Kamat, linux-leds, linux-kernel

fb_notifier_callback is called on any event fired by fb_notifier_call_chain. Events may, or may not contain some data (fb_event.data).
In case of FB_EVENT_BLANK fb_event.data contains a pointer to an integer holding the blank state. The Problem is, that in ledtrig-backlight.c - fb_notifier_callback the pointer to blank state is
dereferenced BEFORE the event-type is checked.
Obviously this leads to problems with other events than FB_EVENT_BLANK, where fb_event.data is undefined or NULL.
It seems, that this problem existed ever since the driver was added.

Like in drivers/video/backlight/backlight.c line 43 I would suggest to return immediately on events other than FB_EVENT_BLANK.

Signed-off-by: Manfred Schlaegl <manfred.schlaegl@gmx.at>
---

Background information:
I'm currently working on a IMX53(ARM) based hardware and Linux 3.11-rc5 and detected a problem in drivers/leds/trigger/ledtrig-backlight.c
ledtrig is used on our hardware (besides pwm-backlight) to switch off a gpio-line connected to display-supply enable-line, when the display is blanked.
On first boot after configuring ledtrig I detected an invalid memory access in ledtrig-backlight.c - fb_notifier_callback. In my special case the segfault was caused by an FB_EVENT_FB_REGISTERED,
fired with undefined fb_event.data in drivers/video/fbmem.c line 1653.


diff --git a/drivers/leds/trigger/ledtrig-backlight.c b/drivers/leds/trigger/ledtrig-backlight.c
index 3c9c88a..2538dbe 100644
--- a/drivers/leds/trigger/ledtrig-backlight.c
+++ b/drivers/leds/trigger/ledtrig-backlight.c
@@ -36,26 +36,28 @@ static int fb_notifier_callback(struct notifier_block *p,
 					struct bl_trig_notifier, notifier);
 	struct led_classdev *led = n->led;
 	struct fb_event *fb_event = data;
-	int *blank = fb_event->data;
-	int new_status = *blank ? BLANK : UNBLANK;
+	int *blank;
+	int new_status;
+
+	/* If we aren't interested in this event, skip it immediately ... */
+	if (event != FB_EVENT_BLANK)
+		return 0;

-	switch (event) {
-	case FB_EVENT_BLANK:
-		if (new_status == n->old_status)
-			break;
+	blank = fb_event->data;
+	new_status = *blank ? BLANK : UNBLANK;

-		if ((n->old_status == UNBLANK) ^ n->invert) {
-			n->brightness = led->brightness;
-			__led_set_brightness(led, LED_OFF);
-		} else {
-			__led_set_brightness(led, n->brightness);
-		}
+	if (new_status == n->old_status)
+		return 0;

-		n->old_status = new_status;
-
-		break;
+	if ((n->old_status == UNBLANK) ^ n->invert) {
+		n->brightness = led->brightness;
+		__led_set_brightness(led, LED_OFF);
+	} else {
+		__led_set_brightness(led, n->brightness);
 	}

+	n->old_status = new_status;
+
 	return 0;
 }





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

* Re: [PATCH] leds: trigger: ledtrig-backlight: Fix invalid memory access in fb_event notification callback
  2013-08-13 11:17 [PATCH] leds: trigger: ledtrig-backlight: Fix invalid memory access in fb_event notification callback Manfred Schlaegl
@ 2013-08-27  0:51 ` Bryan Wu
  2013-08-29 14:31   ` Manfred Schlaegl
  0 siblings, 1 reply; 3+ messages in thread
From: Bryan Wu @ 2013-08-27  0:51 UTC (permalink / raw)
  To: Manfred Schlaegl
  Cc: Richard Purdie, Jingoo Han, Milo(Woogyom) Kim, Sachin Kamat,
	Linux LED Subsystem, lkml

On Tue, Aug 13, 2013 at 4:17 AM, Manfred Schlaegl
<manfred.schlaegl@gmx.at> wrote:
> fb_notifier_callback is called on any event fired by fb_notifier_call_chain. Events may, or may not contain some data (fb_event.data).
> In case of FB_EVENT_BLANK fb_event.data contains a pointer to an integer holding the blank state. The Problem is, that in ledtrig-backlight.c - fb_notifier_callback the pointer to blank state is
> dereferenced BEFORE the event-type is checked.
> Obviously this leads to problems with other events than FB_EVENT_BLANK, where fb_event.data is undefined or NULL.
> It seems, that this problem existed ever since the driver was added.
>
> Like in drivers/video/backlight/backlight.c line 43 I would suggest to return immediately on events other than FB_EVENT_BLANK.
>

Indeed, this is an issue. Thanks for this nice catch and fixing.

I merged this patch into my tree and it will hit 3.11 release.

Thanks,
-Bryan

> Signed-off-by: Manfred Schlaegl <manfred.schlaegl@gmx.at>
> ---
>
> Background information:
> I'm currently working on a IMX53(ARM) based hardware and Linux 3.11-rc5 and detected a problem in drivers/leds/trigger/ledtrig-backlight.c
> ledtrig is used on our hardware (besides pwm-backlight) to switch off a gpio-line connected to display-supply enable-line, when the display is blanked.
> On first boot after configuring ledtrig I detected an invalid memory access in ledtrig-backlight.c - fb_notifier_callback. In my special case the segfault was caused by an FB_EVENT_FB_REGISTERED,
> fired with undefined fb_event.data in drivers/video/fbmem.c line 1653.
>
>
> diff --git a/drivers/leds/trigger/ledtrig-backlight.c b/drivers/leds/trigger/ledtrig-backlight.c
> index 3c9c88a..2538dbe 100644
> --- a/drivers/leds/trigger/ledtrig-backlight.c
> +++ b/drivers/leds/trigger/ledtrig-backlight.c
> @@ -36,26 +36,28 @@ static int fb_notifier_callback(struct notifier_block *p,
>                                         struct bl_trig_notifier, notifier);
>         struct led_classdev *led = n->led;
>         struct fb_event *fb_event = data;
> -       int *blank = fb_event->data;
> -       int new_status = *blank ? BLANK : UNBLANK;
> +       int *blank;
> +       int new_status;
> +
> +       /* If we aren't interested in this event, skip it immediately ... */
> +       if (event != FB_EVENT_BLANK)
> +               return 0;
>
> -       switch (event) {
> -       case FB_EVENT_BLANK:
> -               if (new_status == n->old_status)
> -                       break;
> +       blank = fb_event->data;
> +       new_status = *blank ? BLANK : UNBLANK;
>
> -               if ((n->old_status == UNBLANK) ^ n->invert) {
> -                       n->brightness = led->brightness;
> -                       __led_set_brightness(led, LED_OFF);
> -               } else {
> -                       __led_set_brightness(led, n->brightness);
> -               }
> +       if (new_status == n->old_status)
> +               return 0;
>
> -               n->old_status = new_status;
> -
> -               break;
> +       if ((n->old_status == UNBLANK) ^ n->invert) {
> +               n->brightness = led->brightness;
> +               __led_set_brightness(led, LED_OFF);
> +       } else {
> +               __led_set_brightness(led, n->brightness);
>         }
>
> +       n->old_status = new_status;
> +
>         return 0;
>  }
>
>
>
>

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

* Re: [PATCH] leds: trigger: ledtrig-backlight: Fix invalid memory access in fb_event notification callback
  2013-08-27  0:51 ` Bryan Wu
@ 2013-08-29 14:31   ` Manfred Schlaegl
  0 siblings, 0 replies; 3+ messages in thread
From: Manfred Schlaegl @ 2013-08-29 14:31 UTC (permalink / raw)
  To: Bryan Wu
  Cc: Richard Purdie, Jingoo Han, Milo(Woogyom) Kim, Sachin Kamat,
	Linux LED Subsystem, lkml

On 2013-08-27 02:51, Bryan Wu wrote:
> On Tue, Aug 13, 2013 at 4:17 AM, Manfred Schlaegl
> <manfred.schlaegl@gmx.at> wrote:
>> fb_notifier_callback is called on any event fired by fb_notifier_call_chain. Events may, or may not contain some data (fb_event.data).
>> In case of FB_EVENT_BLANK fb_event.data contains a pointer to an integer holding the blank state. The Problem is, that in ledtrig-backlight.c - fb_notifier_callback the pointer to blank state is
>> dereferenced BEFORE the event-type is checked.
>> Obviously this leads to problems with other events than FB_EVENT_BLANK, where fb_event.data is undefined or NULL.
>> It seems, that this problem existed ever since the driver was added.
>>
>> Like in drivers/video/backlight/backlight.c line 43 I would suggest to return immediately on events other than FB_EVENT_BLANK.
>>
> 
> Indeed, this is an issue. Thanks for this nice catch and fixing.
> 
> I merged this patch into my tree and it will hit 3.11 release.
> 
> Thanks,
> -Bryan

That would be great.
Thanks too.

-manfred


> 
>> Signed-off-by: Manfred Schlaegl <manfred.schlaegl@gmx.at>
>> ---
>>
>> Background information:
>> I'm currently working on a IMX53(ARM) based hardware and Linux 3.11-rc5 and detected a problem in drivers/leds/trigger/ledtrig-backlight.c
>> ledtrig is used on our hardware (besides pwm-backlight) to switch off a gpio-line connected to display-supply enable-line, when the display is blanked.
>> On first boot after configuring ledtrig I detected an invalid memory access in ledtrig-backlight.c - fb_notifier_callback. In my special case the segfault was caused by an FB_EVENT_FB_REGISTERED,
>> fired with undefined fb_event.data in drivers/video/fbmem.c line 1653.
>>
>>
>> diff --git a/drivers/leds/trigger/ledtrig-backlight.c b/drivers/leds/trigger/ledtrig-backlight.c
>> index 3c9c88a..2538dbe 100644
>> --- a/drivers/leds/trigger/ledtrig-backlight.c
>> +++ b/drivers/leds/trigger/ledtrig-backlight.c
>> @@ -36,26 +36,28 @@ static int fb_notifier_callback(struct notifier_block *p,
>>                                         struct bl_trig_notifier, notifier);
>>         struct led_classdev *led = n->led;
>>         struct fb_event *fb_event = data;
>> -       int *blank = fb_event->data;
>> -       int new_status = *blank ? BLANK : UNBLANK;
>> +       int *blank;
>> +       int new_status;
>> +
>> +       /* If we aren't interested in this event, skip it immediately ... */
>> +       if (event != FB_EVENT_BLANK)
>> +               return 0;
>>
>> -       switch (event) {
>> -       case FB_EVENT_BLANK:
>> -               if (new_status == n->old_status)
>> -                       break;
>> +       blank = fb_event->data;
>> +       new_status = *blank ? BLANK : UNBLANK;
>>
>> -               if ((n->old_status == UNBLANK) ^ n->invert) {
>> -                       n->brightness = led->brightness;
>> -                       __led_set_brightness(led, LED_OFF);
>> -               } else {
>> -                       __led_set_brightness(led, n->brightness);
>> -               }
>> +       if (new_status == n->old_status)
>> +               return 0;
>>
>> -               n->old_status = new_status;
>> -
>> -               break;
>> +       if ((n->old_status == UNBLANK) ^ n->invert) {
>> +               n->brightness = led->brightness;
>> +               __led_set_brightness(led, LED_OFF);
>> +       } else {
>> +               __led_set_brightness(led, n->brightness);
>>         }
>>
>> +       n->old_status = new_status;
>> +
>>         return 0;
>>  }
>>
>>
>>
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-leds" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


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

end of thread, other threads:[~2013-08-29 14:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-13 11:17 [PATCH] leds: trigger: ledtrig-backlight: Fix invalid memory access in fb_event notification callback Manfred Schlaegl
2013-08-27  0:51 ` Bryan Wu
2013-08-29 14:31   ` Manfred Schlaegl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox