diff options
author | Manfred Schlaegl <manfred.schlaegl@gmx.at> | 2013-08-13 07:17:05 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@gmail.com> | 2013-08-26 20:46:36 -0400 |
commit | c945cbcf453cb72dc2287fc4f7b63314f173b313 (patch) | |
tree | dd65b5b53670ce33b476ad15a470e9240b032ab7 | |
parent | 8a6acd648c1dfdc82f1bbcd15f7777962054c268 (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.c | 30 |
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 | ||