diff options
author | Sean Young <sean@mess.org> | 2018-07-28 05:11:15 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2018-07-30 08:19:53 -0400 |
commit | f5dbee6e3881b1dbfdcc36008d48bd29549ab2f4 (patch) | |
tree | 0c40f47cfe5fd713d664009851b11b0439f094ad | |
parent | 92cab799bbc6fa1fca84bd1692285a5f926c17e9 (diff) |
media: rc: read out of bounds if bpf reports high protocol number
The repeat period is read from a static array. If a keydown event is
reported from bpf with a high protocol number, we read out of bounds. This
is unlikely to end up with a reasonable repeat period at the best of times,
in which case no timely key up event is generated.
Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
-rw-r--r-- | drivers/media/rc/rc-main.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 2e222d9ee01f..ca68e1d2b2f9 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c | |||
@@ -679,6 +679,14 @@ static void ir_timer_repeat(struct timer_list *t) | |||
679 | spin_unlock_irqrestore(&dev->keylock, flags); | 679 | spin_unlock_irqrestore(&dev->keylock, flags); |
680 | } | 680 | } |
681 | 681 | ||
682 | static unsigned int repeat_period(int protocol) | ||
683 | { | ||
684 | if (protocol >= ARRAY_SIZE(protocols)) | ||
685 | return 100; | ||
686 | |||
687 | return protocols[protocol].repeat_period; | ||
688 | } | ||
689 | |||
682 | /** | 690 | /** |
683 | * rc_repeat() - signals that a key is still pressed | 691 | * rc_repeat() - signals that a key is still pressed |
684 | * @dev: the struct rc_dev descriptor of the device | 692 | * @dev: the struct rc_dev descriptor of the device |
@@ -691,7 +699,7 @@ void rc_repeat(struct rc_dev *dev) | |||
691 | { | 699 | { |
692 | unsigned long flags; | 700 | unsigned long flags; |
693 | unsigned int timeout = nsecs_to_jiffies(dev->timeout) + | 701 | unsigned int timeout = nsecs_to_jiffies(dev->timeout) + |
694 | msecs_to_jiffies(protocols[dev->last_protocol].repeat_period); | 702 | msecs_to_jiffies(repeat_period(dev->last_protocol)); |
695 | struct lirc_scancode sc = { | 703 | struct lirc_scancode sc = { |
696 | .scancode = dev->last_scancode, .rc_proto = dev->last_protocol, | 704 | .scancode = dev->last_scancode, .rc_proto = dev->last_protocol, |
697 | .keycode = dev->keypressed ? dev->last_keycode : KEY_RESERVED, | 705 | .keycode = dev->keypressed ? dev->last_keycode : KEY_RESERVED, |
@@ -803,7 +811,7 @@ void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u32 scancode, | |||
803 | 811 | ||
804 | if (dev->keypressed) { | 812 | if (dev->keypressed) { |
805 | dev->keyup_jiffies = jiffies + nsecs_to_jiffies(dev->timeout) + | 813 | dev->keyup_jiffies = jiffies + nsecs_to_jiffies(dev->timeout) + |
806 | msecs_to_jiffies(protocols[protocol].repeat_period); | 814 | msecs_to_jiffies(repeat_period(protocol)); |
807 | mod_timer(&dev->timer_keyup, dev->keyup_jiffies); | 815 | mod_timer(&dev->timer_keyup, dev->keyup_jiffies); |
808 | } | 816 | } |
809 | spin_unlock_irqrestore(&dev->keylock, flags); | 817 | spin_unlock_irqrestore(&dev->keylock, flags); |