diff options
| author | Dmitry Torokhov <[email protected]> | 2023-06-26 15:18:13 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2023-06-26 15:18:13 -0700 | 
| commit | bf4ed21778f2920ca91a32fd3a1e1130e843e98f (patch) | |
| tree | efb126e6d74ff3ff83913406de136305050c8a80 /drivers/input/misc/uinput.c | |
| parent | feee70f4568650cf44c573488798ffc0a2faeea3 (diff) | |
| parent | 8c9cce9cb81b5fdc6e66bf3f129727b89e8daab7 (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.5 merge window.
Diffstat (limited to 'drivers/input/misc/uinput.c')
| -rw-r--r-- | drivers/input/misc/uinput.c | 34 | 
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index f2593133e524..d98212d55108 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -33,6 +33,7 @@  #define UINPUT_NAME		"uinput"  #define UINPUT_BUFFER_SIZE	16  #define UINPUT_NUM_REQUESTS	16 +#define UINPUT_TIMESTAMP_ALLOWED_OFFSET_SECS 10  enum uinput_state { UIST_NEW_DEVICE, UIST_SETUP_COMPLETE, UIST_CREATED }; @@ -569,11 +570,40 @@ static int uinput_setup_device_legacy(struct uinput_device *udev,  	return retval;  } +/* + * Returns true if the given timestamp is valid (i.e., if all the following + * conditions are satisfied), false otherwise. + * 1) given timestamp is positive + * 2) it's within the allowed offset before the current time + * 3) it's not in the future + */ +static bool is_valid_timestamp(const ktime_t timestamp) +{ +	ktime_t zero_time; +	ktime_t current_time; +	ktime_t min_time; +	ktime_t offset; + +	zero_time = ktime_set(0, 0); +	if (ktime_compare(zero_time, timestamp) >= 0) +		return false; + +	current_time = ktime_get(); +	offset = ktime_set(UINPUT_TIMESTAMP_ALLOWED_OFFSET_SECS, 0); +	min_time = ktime_sub(current_time, offset); + +	if (ktime_after(min_time, timestamp) || ktime_after(timestamp, current_time)) +		return false; + +	return true; +} +  static ssize_t uinput_inject_events(struct uinput_device *udev,  				    const char __user *buffer, size_t count)  {  	struct input_event ev;  	size_t bytes = 0; +	ktime_t timestamp;  	if (count != 0 && count < input_event_size())  		return -EINVAL; @@ -588,6 +618,10 @@ static ssize_t uinput_inject_events(struct uinput_device *udev,  		if (input_event_from_user(buffer + bytes, &ev))  			return -EFAULT; +		timestamp = ktime_set(ev.input_event_sec, ev.input_event_usec * NSEC_PER_USEC); +		if (is_valid_timestamp(timestamp)) +			input_set_timestamp(udev->dev, timestamp); +  		input_event(udev->dev, ev.type, ev.code, ev.value);  		bytes += input_event_size();  		cond_resched();  |