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

Commit 24ff05e7 authored by Mark Salyzyn's avatar Mark Salyzyn
Browse files

Revert "ANDROID: input: keychord: Fix races in keychord_write."

This reverts commit 8253552b.

Remove keychord driver, replaced in user space by
https://android-review.googlesource.com/c/677629

.

Signed-off-by: default avatarMark Salyzyn <salyzyn@google.com>
Bug: 64114943
Bug: 64133562
Bug: 63974334
Bug: 129556081
Change-Id: Ie94621b0adf8b1f8c0d249f74385cc2914b1aec0
parent 3909bbc1
Loading
Loading
Loading
Loading
+1 −60
Original line number Diff line number Diff line
@@ -60,10 +60,6 @@ struct keychord_device {
	unsigned char		head;
	unsigned char		tail;
	__u16			buff[BUFFER_SIZE];
	/* Bit to serialize writes to this device */
#define KEYCHORD_BUSY			0x01
	unsigned long		flags;
	wait_queue_head_t	write_waitq;
};

static int check_keychord(struct keychord_device *kdev,
@@ -176,6 +172,7 @@ static int keychord_connect(struct input_handler *handler,
		goto err_input_open_device;

	pr_info("keychord: using input dev %s for fevent\n", dev->name);

	return 0;

err_input_open_device:
@@ -227,41 +224,6 @@ static ssize_t keychord_read(struct file *file, char __user *buffer,
	return count;
}

/*
 * serializes writes on a device. can use mutex_lock_interruptible()
 * for this particular use case as well - a matter of preference.
 */
static int
keychord_write_lock(struct keychord_device *kdev)
{
	int ret;
	unsigned long flags;

	spin_lock_irqsave(&kdev->lock, flags);
	while (kdev->flags & KEYCHORD_BUSY) {
		spin_unlock_irqrestore(&kdev->lock, flags);
		ret = wait_event_interruptible(kdev->write_waitq,
			       ((kdev->flags & KEYCHORD_BUSY) == 0));
		if (ret)
			return ret;
		spin_lock_irqsave(&kdev->lock, flags);
	}
	kdev->flags |= KEYCHORD_BUSY;
	spin_unlock_irqrestore(&kdev->lock, flags);
	return 0;
}

static void
keychord_write_unlock(struct keychord_device *kdev)
{
	unsigned long flags;

	spin_lock_irqsave(&kdev->lock, flags);
	kdev->flags &= ~KEYCHORD_BUSY;
	spin_unlock_irqrestore(&kdev->lock, flags);
	wake_up_interruptible(&kdev->write_waitq);
}

/*
 * keychord_write is used to configure the driver
 */
@@ -288,22 +250,6 @@ static ssize_t keychord_write(struct file *file, const char __user *buffer,
		return -EFAULT;
	}

	/*
	 * Serialize writes to this device to prevent various races.
	 * 1) writers racing here could do duplicate input_unregister_handler()
	 *    calls, resulting in attempting to unlink a node from a list that
	 *    does not exist.
	 * 2) writers racing here could do duplicate input_register_handler() calls
	 *    below, resulting in a duplicate insertion of a node into the list.
	 * 3) a double kfree of keychords can occur (in the event that
	 *    input_register_handler() fails below.
	 */
	ret = keychord_write_lock(kdev);
	if (ret) {
		kfree(keychords);
		return ret;
	}

	/* unregister handler before changing configuration */
	if (kdev->registered) {
		input_unregister_handler(&kdev->input_handler);
@@ -372,19 +318,15 @@ static ssize_t keychord_write(struct file *file, const char __user *buffer,
	if (ret) {
		kfree(keychords);
		kdev->keychords = 0;
		keychord_write_unlock(kdev);
		return ret;
	}
	kdev->registered = 1;

	keychord_write_unlock(kdev);

	return count;

err_unlock_return:
	spin_unlock_irqrestore(&kdev->lock, flags);
	kfree(keychords);
	keychord_write_unlock(kdev);
	return -EINVAL;
}

@@ -410,7 +352,6 @@ static int keychord_open(struct inode *inode, struct file *file)

	spin_lock_init(&kdev->lock);
	init_waitqueue_head(&kdev->waitq);
	init_waitqueue_head(&kdev->write_waitq);

	kdev->input_handler.event = keychord_event;
	kdev->input_handler.connect = keychord_connect;