Periodic: add error handling for integer overflow
Bug: 205995773
Test: GCA, test_poc, CTS
Signed-off-by: Nick Chung <nickchung@google.com>
Change-Id: I6fecab84188511bf36f4ff8b6cf839c7ec099738
diff --git a/lwis_ioctl.c b/lwis_ioctl.c
index 7453d8b..8033da6 100644
--- a/lwis_ioctl.c
+++ b/lwis_ioctl.c
@@ -1097,6 +1097,11 @@
struct lwis_device *lwis_dev = client->lwis_dev;
entry_size = num_io_entries * sizeof(struct lwis_io_entry);
+ if (entry_size / sizeof(struct lwis_io_entry) != num_io_entries) {
+ dev_err(lwis_dev->dev, "Failed to prepare io entry due to integer overflow\n");
+ return -EINVAL;
+ }
+
k_entries = kvmalloc(entry_size, GFP_KERNEL);
if (!k_entries) {
dev_err(lwis_dev->dev, "Failed to allocate periodic io entries\n");
diff --git a/lwis_periodic_io.c b/lwis_periodic_io.c
index 061eced..6c7fed1 100644
--- a/lwis_periodic_io.c
+++ b/lwis_periodic_io.c
@@ -378,6 +378,26 @@
}
}
+ /* Check integer overflow.*/
+ if (info->batch_size != 0 && read_entries != 0 && read_buf_size != 0) {
+ if (SIZE_MAX / (sizeof(struct lwis_periodic_io_result) * info->batch_size) <
+ read_entries ||
+ SIZE_MAX / (read_entries * sizeof(struct lwis_periodic_io_result)) <
+ info->batch_size ||
+ SIZE_MAX / read_buf_size < info->batch_size ||
+ SIZE_MAX - (read_entries * sizeof(struct lwis_periodic_io_result) *
+ info->batch_size +
+ read_buf_size * info->batch_size) <
+ sizeof(struct lwis_periodic_io_response_header) ||
+ SIZE_MAX - (read_entries * sizeof(struct lwis_periodic_io_result) *
+ info->batch_size +
+ sizeof(struct lwis_periodic_io_response_header)) <
+ (read_buf_size * info->batch_size)) {
+ pr_err_ratelimited("Failed to prepare response due to integer overflow\n");
+ return -EINVAL;
+ }
+ }
+
/* Periodic io response payload consists of one response header and
* batch_size of batches, each of which contains num_entries_per_period
* pairs of lwis_periodic_io_result and its read_buf. */
@@ -427,10 +447,10 @@
int i;
for (i = 0; i < periodic_io->info.num_io_entries; ++i) {
if (periodic_io->info.io_entries[i].type == LWIS_IO_ENTRY_WRITE_BATCH) {
- kfree(periodic_io->info.io_entries[i].rw_batch.buf);
+ kvfree(periodic_io->info.io_entries[i].rw_batch.buf);
}
}
- kfree(periodic_io->info.io_entries);
+ kvfree(periodic_io->info.io_entries);
/* resp may not be allocated before the periodic_io is successfully
* submitted */