summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHolmes Chou <holmeschou@google.com>2022-05-27 06:24:29 +0000
committerTreeHugger Robot <treehugger-gerrit@google.com>2022-05-27 17:29:21 +0000
commit90393f037049dc2efe00aba33df858a70fd596ea (patch)
treeeb9dc790dd1176f1696b615647ebb1f8f03e5a9c
parenta5b1ac659e65a7eeb6d1c7970ac577b665fa8b9f (diff)
downloadlwis-90393f037049dc2efe00aba33df858a70fd596ea.tar.gz
LWIS: Add mutex to prevent peek event to be freed
When dequeue an event, if the device reset is called at the same time, it will have chance the accessing event to be freed and cause invalid access. Add mutex to protect this case. Bug: 232053886 Test: GCA, CTS Change-Id: I527e5efc2a2b2a452638627da62f97c08b49e919
-rw-r--r--lwis_ioctl.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/lwis_ioctl.c b/lwis_ioctl.c
index d72d32f..4ec8f8d 100644
--- a/lwis_ioctl.c
+++ b/lwis_ioctl.c
@@ -878,12 +878,14 @@ static int ioctl_event_dequeue(struct lwis_client *lwis_client, struct lwis_even
return -EFAULT;
}
+ mutex_lock(&lwis_dev->client_lock);
/* Peek at the front element of error event queue first */
ret = lwis_client_error_event_peek_front(lwis_client, &event);
if (ret == 0) {
is_error_event = true;
} else if (ret != -ENOENT) {
dev_err(lwis_dev->dev, "Error dequeueing error event: %ld\n", ret);
+ mutex_unlock(&lwis_dev->client_lock);
return ret;
} else {
/* Nothing at error event queue, continue to check normal
@@ -893,6 +895,7 @@ static int ioctl_event_dequeue(struct lwis_client *lwis_client, struct lwis_even
if (ret != -ENOENT) {
dev_err(lwis_dev->dev, "Error dequeueing event: %ld\n", ret);
}
+ mutex_unlock(&lwis_dev->client_lock);
return ret;
}
}
@@ -924,6 +927,7 @@ static int ioctl_event_dequeue(struct lwis_client *lwis_client, struct lwis_even
event->event_info.payload_size)) {
dev_err(lwis_dev->dev, "Failed to copy %zu bytes to user\n",
event->event_info.payload_size);
+ mutex_unlock(&lwis_dev->client_lock);
return -EFAULT;
}
}
@@ -941,9 +945,11 @@ static int ioctl_event_dequeue(struct lwis_client *lwis_client, struct lwis_even
}
if (ret) {
dev_err(lwis_dev->dev, "Error dequeueing event: %ld\n", ret);
+ mutex_unlock(&lwis_dev->client_lock);
return ret;
}
}
+ mutex_unlock(&lwis_dev->client_lock);
/* Now let's copy the actual info struct back to user */
if (copy_to_user((void __user *)msg, (void *)&info_user, sizeof(info_user))) {
dev_err(lwis_dev->dev, "Failed to copy %zu bytes to user\n", sizeof(info_user));