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

Commit 843e784a authored by Dmitry Torokhov's avatar Dmitry Torokhov
Browse files

Input: serio_raw - perform proper locking when adding clients to list



Make sure we hold serio lock when adding clients to client list so that
we do not race with serio_raw_release() removing clients from the same
list.

Reviewed-by: default avatarWanlong Gao <gaowanlong@cn.fujitsu.com>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 7c5bbb2e
Loading
Loading
Loading
Loading
+5 −3
Original line number Original line Diff line number Diff line
@@ -106,7 +106,10 @@ static int serio_raw_open(struct inode *inode, struct file *file)
	file->private_data = client;
	file->private_data = client;


	kref_get(&serio_raw->kref);
	kref_get(&serio_raw->kref);

	serio_pause_rx(serio_raw->serio);
	list_add_tail(&client->node, &serio_raw->client_list);
	list_add_tail(&client->node, &serio_raw->client_list);
	serio_continue_rx(serio_raw->serio);


out:
out:
	mutex_unlock(&serio_raw_mutex);
	mutex_unlock(&serio_raw_mutex);
@@ -138,10 +141,9 @@ static int serio_raw_release(struct inode *inode, struct file *file)


static int serio_raw_fetch_byte(struct serio_raw *serio_raw, char *c)
static int serio_raw_fetch_byte(struct serio_raw *serio_raw, char *c)
{
{
	unsigned long flags;
	int empty;
	int empty;


	spin_lock_irqsave(&serio_raw->serio->lock, flags);
	serio_pause_rx(serio_raw->serio);


	empty = serio_raw->head == serio_raw->tail;
	empty = serio_raw->head == serio_raw->tail;
	if (!empty) {
	if (!empty) {
@@ -149,7 +151,7 @@ static int serio_raw_fetch_byte(struct serio_raw *serio_raw, char *c)
		serio_raw->tail = (serio_raw->tail + 1) % SERIO_RAW_QUEUE_LEN;
		serio_raw->tail = (serio_raw->tail + 1) % SERIO_RAW_QUEUE_LEN;
	}
	}


	spin_unlock_irqrestore(&serio_raw->serio->lock, flags);
	serio_continue_rx(serio_raw->serio);


	return !empty;
	return !empty;
}
}