Commit b590c0bf authored by Sean Young's avatar Sean Young Committed by Mauro Carvalho Chehab

[media] rc: Add scancode validation

We need to valdiate that scancodes are valid for their protocol; an
incorrect necx scancode could actually be a nec scancode, for example.
Signed-off-by: default avatarSean Young <sean@mess.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent 0751d33c
...@@ -724,6 +724,64 @@ void rc_keydown_notimeout(struct rc_dev *dev, enum rc_type protocol, ...@@ -724,6 +724,64 @@ void rc_keydown_notimeout(struct rc_dev *dev, enum rc_type protocol,
} }
EXPORT_SYMBOL_GPL(rc_keydown_notimeout); EXPORT_SYMBOL_GPL(rc_keydown_notimeout);
/**
* rc_validate_filter() - checks that the scancode and mask are valid and
* provides sensible defaults
* @protocol: the protocol for the filter
* @filter: the scancode and mask
* @return: 0 or -EINVAL if the filter is not valid
*/
static int rc_validate_filter(enum rc_type protocol,
struct rc_scancode_filter *filter)
{
static u32 masks[] = {
[RC_TYPE_RC5] = 0x1f7f,
[RC_TYPE_RC5X_20] = 0x1f7f3f,
[RC_TYPE_RC5_SZ] = 0x2fff,
[RC_TYPE_SONY12] = 0x1f007f,
[RC_TYPE_SONY15] = 0xff007f,
[RC_TYPE_SONY20] = 0x1fff7f,
[RC_TYPE_JVC] = 0xffff,
[RC_TYPE_NEC] = 0xffff,
[RC_TYPE_NECX] = 0xffffff,
[RC_TYPE_NEC32] = 0xffffffff,
[RC_TYPE_SANYO] = 0x1fffff,
[RC_TYPE_RC6_0] = 0xffff,
[RC_TYPE_RC6_6A_20] = 0xfffff,
[RC_TYPE_RC6_6A_24] = 0xffffff,
[RC_TYPE_RC6_6A_32] = 0xffffffff,
[RC_TYPE_RC6_MCE] = 0xffff7fff,
[RC_TYPE_SHARP] = 0x1fff,
};
u32 s = filter->data;
switch (protocol) {
case RC_TYPE_NECX:
if ((((s >> 16) ^ ~(s >> 8)) & 0xff) == 0)
return -EINVAL;
break;
case RC_TYPE_NEC32:
if ((((s >> 24) ^ ~(s >> 16)) & 0xff) == 0)
return -EINVAL;
break;
case RC_TYPE_RC6_MCE:
if ((s & 0xffff0000) != 0x800f0000)
return -EINVAL;
break;
case RC_TYPE_RC6_6A_32:
if ((s & 0xffff0000) == 0x800f0000)
return -EINVAL;
break;
default:
break;
}
filter->data &= masks[protocol];
filter->mask &= masks[protocol];
return 0;
}
int rc_open(struct rc_dev *rdev) int rc_open(struct rc_dev *rdev)
{ {
int rval = 0; int rval = 0;
...@@ -1229,11 +1287,18 @@ static ssize_t store_filter(struct device *device, ...@@ -1229,11 +1287,18 @@ static ssize_t store_filter(struct device *device,
new_filter.data = val; new_filter.data = val;
if (fattr->type == RC_FILTER_WAKEUP) { if (fattr->type == RC_FILTER_WAKEUP) {
/* refuse to set a filter unless a protocol is enabled */ /*
if (dev->wakeup_protocol == RC_TYPE_UNKNOWN) { * Refuse to set a filter unless a protocol is enabled
* and the filter is valid for that protocol
*/
if (dev->wakeup_protocol != RC_TYPE_UNKNOWN)
ret = rc_validate_filter(dev->wakeup_protocol,
&new_filter);
else
ret = -EINVAL; ret = -EINVAL;
if (ret != 0)
goto unlock; goto unlock;
}
} }
if (fattr->type == RC_FILTER_NORMAL && !dev->enabled_protocols && if (fattr->type == RC_FILTER_NORMAL && !dev->enabled_protocols &&
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment