Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5fdbe44d authored by Dmitry Torokhov's avatar Dmitry Torokhov
Browse files

Input: do not pass injected events back to the originating handler



Sometimes input handlers (as opposed to input devices) have a need to
inject (or re-inject) events back into input core. For example sysrq
filter may want to inject previously suppressed Alt-SysRq so that user
can take a screen print. In this case we do not want to pass such events
back to the same same handler that injected them to avoid loops.

Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 17d01f28
Loading
Loading
Loading
Loading
+26 −11
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz)
 * dev->event_lock held and interrupts disabled.
 */
static void input_pass_event(struct input_dev *dev,
			     struct input_handler *src_handler,
			     unsigned int type, unsigned int code, int value)
{
	struct input_handler *handler;
@@ -92,6 +93,15 @@ static void input_pass_event(struct input_dev *dev,
				continue;

			handler = handle->handler;

			/*
			 * If this is the handler that injected this
			 * particular event we want to skip it to avoid
			 * filters firing again and again.
			 */
			if (handler == src_handler)
				continue;

			if (!handler->filter) {
				if (filtered)
					break;
@@ -121,7 +131,7 @@ static void input_repeat_key(unsigned long data)
	if (test_bit(dev->repeat_key, dev->key) &&
	    is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) {

		input_pass_event(dev, EV_KEY, dev->repeat_key, 2);
		input_pass_event(dev, NULL, EV_KEY, dev->repeat_key, 2);

		if (dev->sync) {
			/*
@@ -130,7 +140,7 @@ static void input_repeat_key(unsigned long data)
			 * Otherwise assume that the driver will send
			 * SYN_REPORT once it's done.
			 */
			input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
			input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
		}

		if (dev->rep[REP_PERIOD])
@@ -163,6 +173,7 @@ static void input_stop_autorepeat(struct input_dev *dev)
#define INPUT_PASS_TO_ALL	(INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE)

static int input_handle_abs_event(struct input_dev *dev,
				  struct input_handler *src_handler,
				  unsigned int code, int *pval)
{
	bool is_mt_event;
@@ -206,13 +217,15 @@ static int input_handle_abs_event(struct input_dev *dev,
	/* Flush pending "slot" event */
	if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) {
		input_abs_set_val(dev, ABS_MT_SLOT, dev->slot);
		input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot);
		input_pass_event(dev, src_handler,
				 EV_ABS, ABS_MT_SLOT, dev->slot);
	}

	return INPUT_PASS_TO_HANDLERS;
}

static void input_handle_event(struct input_dev *dev,
			       struct input_handler *src_handler,
			       unsigned int type, unsigned int code, int value)
{
	int disposition = INPUT_IGNORE_EVENT;
@@ -265,7 +278,8 @@ static void input_handle_event(struct input_dev *dev,

	case EV_ABS:
		if (is_event_supported(code, dev->absbit, ABS_MAX))
			disposition = input_handle_abs_event(dev, code, &value);
			disposition = input_handle_abs_event(dev, src_handler,
							     code, &value);

		break;

@@ -323,7 +337,7 @@ static void input_handle_event(struct input_dev *dev,
		dev->event(dev, type, code, value);

	if (disposition & INPUT_PASS_TO_HANDLERS)
		input_pass_event(dev, type, code, value);
		input_pass_event(dev, src_handler, type, code, value);
}

/**
@@ -352,7 +366,7 @@ void input_event(struct input_dev *dev,

		spin_lock_irqsave(&dev->event_lock, flags);
		add_input_randomness(type, code, value);
		input_handle_event(dev, type, code, value);
		input_handle_event(dev, NULL, type, code, value);
		spin_unlock_irqrestore(&dev->event_lock, flags);
	}
}
@@ -382,7 +396,8 @@ void input_inject_event(struct input_handle *handle,
		rcu_read_lock();
		grab = rcu_dereference(dev->grab);
		if (!grab || grab == handle)
			input_handle_event(dev, type, code, value);
			input_handle_event(dev, handle->handler,
					   type, code, value);
		rcu_read_unlock();

		spin_unlock_irqrestore(&dev->event_lock, flags);
@@ -595,10 +610,10 @@ static void input_dev_release_keys(struct input_dev *dev)
		for (code = 0; code <= KEY_MAX; code++) {
			if (is_event_supported(code, dev->keybit, KEY_MAX) &&
			    __test_and_clear_bit(code, dev->key)) {
				input_pass_event(dev, EV_KEY, code, 0);
				input_pass_event(dev, NULL, EV_KEY, code, 0);
			}
		}
		input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
		input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
	}
}

@@ -873,9 +888,9 @@ int input_set_keycode(struct input_dev *dev,
	    !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
	    __test_and_clear_bit(old_keycode, dev->key)) {

		input_pass_event(dev, EV_KEY, old_keycode, 0);
		input_pass_event(dev, NULL, EV_KEY, old_keycode, 0);
		if (dev->sync)
			input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
			input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
	}

 out: