Message ID | 20200421231003.7935-1-bshanks@codeweavers.com (mailing list archive) |
---|---|
State | Accepted |
Commit | 09264098ff153f60866039d60b31d39b66f55a31 |
Headers | show |
Series | Input: evdev - Call input_flush_device() on release(), not flush() | expand |
On Tue, Apr 21, 2020 at 04:10:03PM -0700, Brendan Shanks wrote: > input_flush_device() should only be called once the struct file is being > released and no open descriptors remain, but evdev_flush() was calling > it whenever a file descriptor was closed. > > This caused uploaded force-feedback effects to be erased when a process > did a dup()/close() on the event FD, called system(), etc. > > Call input_flush_device() from evdev_release() instead. > > Reported-by: Mathieu Maret <mathieu.maret@gmail.com> > Signed-off-by: Brendan Shanks <bshanks@codeweavers.com> Applied, thank you. > --- > drivers/input/evdev.c | 18 +++--------------- > 1 file changed, 3 insertions(+), 15 deletions(-) > > diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c > index cb6e3a5f509c..3c006b265729 100644 > --- a/drivers/input/evdev.c > +++ b/drivers/input/evdev.c > @@ -326,20 +326,6 @@ static int evdev_fasync(int fd, struct file *file, int on) > return fasync_helper(fd, file, on, &client->fasync); > } > > -static int evdev_flush(struct file *file, fl_owner_t id) > -{ > - struct evdev_client *client = file->private_data; > - struct evdev *evdev = client->evdev; > - > - mutex_lock(&evdev->mutex); > - > - if (evdev->exist && !client->revoked) > - input_flush_device(&evdev->handle, file); > - > - mutex_unlock(&evdev->mutex); > - return 0; > -} > - > static void evdev_free(struct device *dev) > { > struct evdev *evdev = container_of(dev, struct evdev, dev); > @@ -453,6 +439,9 @@ static int evdev_release(struct inode *inode, struct file *file) > unsigned int i; > > mutex_lock(&evdev->mutex); > + if (evdev->exist && !client->revoked) > + input_flush_device(&evdev->handle, file); > + > evdev_ungrab(evdev, client); > mutex_unlock(&evdev->mutex); > > @@ -1310,7 +1299,6 @@ static const struct file_operations evdev_fops = { > .compat_ioctl = evdev_ioctl_compat, > #endif > .fasync = evdev_fasync, > - .flush = evdev_flush, > .llseek = no_llseek, > }; > > -- > 2.25.3 >
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index cb6e3a5f509c..3c006b265729 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -326,20 +326,6 @@ static int evdev_fasync(int fd, struct file *file, int on) return fasync_helper(fd, file, on, &client->fasync); } -static int evdev_flush(struct file *file, fl_owner_t id) -{ - struct evdev_client *client = file->private_data; - struct evdev *evdev = client->evdev; - - mutex_lock(&evdev->mutex); - - if (evdev->exist && !client->revoked) - input_flush_device(&evdev->handle, file); - - mutex_unlock(&evdev->mutex); - return 0; -} - static void evdev_free(struct device *dev) { struct evdev *evdev = container_of(dev, struct evdev, dev); @@ -453,6 +439,9 @@ static int evdev_release(struct inode *inode, struct file *file) unsigned int i; mutex_lock(&evdev->mutex); + if (evdev->exist && !client->revoked) + input_flush_device(&evdev->handle, file); + evdev_ungrab(evdev, client); mutex_unlock(&evdev->mutex); @@ -1310,7 +1299,6 @@ static const struct file_operations evdev_fops = { .compat_ioctl = evdev_ioctl_compat, #endif .fasync = evdev_fasync, - .flush = evdev_flush, .llseek = no_llseek, };
input_flush_device() should only be called once the struct file is being released and no open descriptors remain, but evdev_flush() was calling it whenever a file descriptor was closed. This caused uploaded force-feedback effects to be erased when a process did a dup()/close() on the event FD, called system(), etc. Call input_flush_device() from evdev_release() instead. Reported-by: Mathieu Maret <mathieu.maret@gmail.com> Signed-off-by: Brendan Shanks <bshanks@codeweavers.com> --- drivers/input/evdev.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-)