aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManfred Schlaegl <manfred.schlaegl@gmx.at>2013-08-13 07:17:05 -0400
committerBryan Wu <cooloney@gmail.com>2013-08-26 20:46:36 -0400
commitc945cbcf453cb72dc2287fc4f7b63314f173b313 (patch)
treedd65b5b53670ce33b476ad15a470e9240b032ab7
parent8a6acd648c1dfdc82f1bbcd15f7777962054c268 (diff)
leds: trigger: ledtrig-backlight: Fix invalid memory access in fb_event notification callback
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 holdingthe 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> Signed-off-by: Bryan Wu <cooloney@gmail.com>
-rw-r--r--drivers/leds/trigger/ledtrig-backlight.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/drivers/leds/trigger/ledtrig-backlight.c b/drivers/leds/trigger/ledtrig-backlight.c
index 3c9c88a07eb8..47e55aa9eefa 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,
36 struct bl_trig_notifier, notifier); 36 struct bl_trig_notifier, notifier);
37 struct led_classdev *led = n->led; 37 struct led_classdev *led = n->led;
38 struct fb_event *fb_event = data; 38 struct fb_event *fb_event = data;
39 int *blank = fb_event->data; 39 int *blank;
40 int new_status = *blank ? BLANK : UNBLANK; 40 int new_status;
41 41
42 switch (event) { 42 /* If we aren't interested in this event, skip it immediately ... */
43 case FB_EVENT_BLANK: 43 if (event != FB_EVENT_BLANK)
44 if (new_status == n->old_status) 44 return 0;
45 break;
46 45
47 if ((n->old_status == UNBLANK) ^ n->invert) { 46 blank = fb_event->data;
48 n->brightness = led->brightness; 47 new_status = *blank ? BLANK : UNBLANK;
49 __led_set_brightness(led, LED_OFF);
50 } else {
51 __led_set_brightness(led, n->brightness);
52 }
53 48
54 n->old_status = new_status; 49 if (new_status == n->old_status)
50 return 0;
55 51
56 break; 52 if ((n->old_status == UNBLANK) ^ n->invert) {
53 n->brightness = led->brightness;
54 __led_set_brightness(led, LED_OFF);
55 } else {
56 __led_set_brightness(led, n->brightness);
57 } 57 }
58 58
59 n->old_status = new_status;
60
59 return 0; 61 return 0;
60} 62}
61 63