Skip to content

Commit

Permalink
Input: gpio-keys - fix check for disabling unsupported keys
Browse files Browse the repository at this point in the history
Commit 4ea14a5 ("Input: gpio-keys - report
error when disabling unsupported key") tried let user know that they
attempted to disable an unsupported key, unfortunately the check is wrong
as it believes that all codes are invalid. Fix it by ensuring that keys
that we try to disable are subset of keys (or switches) that device
reports.

Fixes: 4ea14a5 ("Input: gpio-keys - report error when disabling unsupported key")
Reported-by: Ivaylo Dimitrov <[email protected]>
Tested-by: Ivaylo Dimitrov <[email protected]>
Signed-off-by: Dmitry Torokhov <[email protected]>
  • Loading branch information
dtor committed Jan 10, 2016
1 parent 35f8679 commit 8679ee4
Showing 1 changed file with 23 additions and 6 deletions.
29 changes: 23 additions & 6 deletions drivers/input/keyboard/gpio_keys.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,29 @@ struct gpio_keys_drvdata {
* Return value of this function can be used to allocate bitmap
* large enough to hold all bits for given type.
*/
static inline int get_n_events_by_type(int type)
static int get_n_events_by_type(int type)
{
BUG_ON(type != EV_SW && type != EV_KEY);

return (type == EV_KEY) ? KEY_CNT : SW_CNT;
}

/**
* get_bm_events_by_type() - returns bitmap of supported events per @type
* @input: input device from which bitmap is retrieved
* @type: type of button (%EV_KEY, %EV_SW)
*
* Return value of this function can be used to allocate bitmap
* large enough to hold all bits for given type.
*/
static const unsigned long *get_bm_events_by_type(struct input_dev *dev,
int type)
{
BUG_ON(type != EV_SW && type != EV_KEY);

return (type == EV_KEY) ? dev->keybit : dev->swbit;
}

/**
* gpio_keys_disable_button() - disables given GPIO button
* @bdata: button data for button to be disabled
Expand Down Expand Up @@ -213,6 +229,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata,
const char *buf, unsigned int type)
{
int n_events = get_n_events_by_type(type);
const unsigned long *bitmap = get_bm_events_by_type(ddata->input, type);
unsigned long *bits;
ssize_t error;
int i;
Expand All @@ -226,6 +243,11 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata,
goto out;

/* First validate */
if (!bitmap_subset(bits, bitmap, n_events)) {
error = -EINVAL;
goto out;
}

for (i = 0; i < ddata->pdata->nbuttons; i++) {
struct gpio_button_data *bdata = &ddata->data[i];

Expand All @@ -239,11 +261,6 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata,
}
}

if (i == ddata->pdata->nbuttons) {
error = -EINVAL;
goto out;
}

mutex_lock(&ddata->disable_lock);

for (i = 0; i < ddata->pdata->nbuttons; i++) {
Expand Down

0 comments on commit 8679ee4

Please sign in to comment.