summaryrefslogtreecommitdiff
path: root/dvalin/kernel/drivers/gpu/arm/midgard/mali_kbase_debugfs_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'dvalin/kernel/drivers/gpu/arm/midgard/mali_kbase_debugfs_helper.c')
-rw-r--r--dvalin/kernel/drivers/gpu/arm/midgard/mali_kbase_debugfs_helper.c104
1 files changed, 85 insertions, 19 deletions
diff --git a/dvalin/kernel/drivers/gpu/arm/midgard/mali_kbase_debugfs_helper.c b/dvalin/kernel/drivers/gpu/arm/midgard/mali_kbase_debugfs_helper.c
index 37e507b..973739f 100644
--- a/dvalin/kernel/drivers/gpu/arm/midgard/mali_kbase_debugfs_helper.c
+++ b/dvalin/kernel/drivers/gpu/arm/midgard/mali_kbase_debugfs_helper.c
@@ -1,11 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
*
- * (C) COPYRIGHT 2019 ARM Limited. All rights reserved.
+ * (C) COPYRIGHT 2019-2021 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation, and any use by you of this program is subject to the terms
- * of such GNU licence.
+ * of such GNU license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -16,8 +17,6 @@
* along with this program; if not, you can access it online at
* http://www.gnu.org/licenses/gpl-2.0.html.
*
- * SPDX-License-Identifier: GPL-2.0
- *
*/
#include <linux/debugfs.h>
@@ -46,10 +45,9 @@
*
* Return: 0 if success, negative error code otherwise.
*/
-static int set_attr_from_string(
- char *const buf,
- void *const array, size_t const nelems,
- kbase_debugfs_helper_set_attr_fn const set_attr_fn)
+static int
+set_attr_from_string(char *const buf, void *const array, size_t const nelems,
+ kbase_debugfs_helper_set_attr_fn *const set_attr_fn)
{
size_t index, err = 0;
char *ptr = buf;
@@ -90,9 +88,62 @@ static int set_attr_from_string(
return err;
}
+int kbase_debugfs_string_validator(char *const buf)
+{
+ size_t index;
+ int err = 0;
+ char *ptr = buf;
+
+ for (index = 0; *ptr; ++index) {
+ unsigned long test_number;
+ size_t len;
+
+ /* Drop leading spaces */
+ while (*ptr == ' ')
+ ptr++;
+
+ /* Strings passed into the validator will be NULL terminated
+ * by nature, so here strcspn only needs to delimit by
+ * newlines, spaces and NULL terminator (delimited natively).
+ */
+ len = strcspn(ptr, "\n ");
+ if (len == 0) {
+ /* No more values (allow this) */
+ break;
+ }
+
+ /* Substitute a nul terminator for a space character to make
+ * the substring valid for kstrtoul, and then replace it back.
+ */
+ if (ptr[len] == ' ') {
+ ptr[len] = '\0';
+ err = kstrtoul(ptr, 0, &test_number);
+ ptr[len] = ' ';
+
+ /* len should only be incremented if there is a valid
+ * number to follow - otherwise this will skip over
+ * the NULL terminator in cases with no ending newline
+ */
+ len++;
+ } else {
+ /* This would occur at the last element before a space
+ * or a NULL terminator.
+ */
+ err = kstrtoul(ptr, 0, &test_number);
+ }
+
+ if (err)
+ break;
+ /* Skip the substring (including any premature nul terminator)
+ */
+ ptr += len;
+ }
+ return err;
+}
+
int kbase_debugfs_helper_set_attr_from_string(
const char *const buf, void *const array, size_t const nelems,
- kbase_debugfs_helper_set_attr_fn const set_attr_fn)
+ kbase_debugfs_helper_set_attr_fn *const set_attr_fn)
{
char *const wbuf = kstrdup(buf, GFP_KERNEL);
int err = 0;
@@ -100,6 +151,13 @@ int kbase_debugfs_helper_set_attr_from_string(
if (!wbuf)
return -ENOMEM;
+ /* validate string before actually writing values */
+ err = kbase_debugfs_string_validator(wbuf);
+ if (err) {
+ kfree(wbuf);
+ return err;
+ }
+
err = set_attr_from_string(wbuf, array, nelems,
set_attr_fn);
@@ -108,9 +166,9 @@ int kbase_debugfs_helper_set_attr_from_string(
}
ssize_t kbase_debugfs_helper_get_attr_to_string(
- char *const buf, size_t const size,
- void *const array, size_t const nelems,
- kbase_debugfs_helper_get_attr_fn const get_attr_fn)
+ char *const buf, size_t const size, void *const array,
+ size_t const nelems,
+ kbase_debugfs_helper_get_attr_fn *const get_attr_fn)
{
ssize_t total = 0;
size_t index;
@@ -128,10 +186,10 @@ ssize_t kbase_debugfs_helper_get_attr_to_string(
return total;
}
-int kbase_debugfs_helper_seq_write(struct file *const file,
- const char __user *const ubuf, size_t const count,
- size_t const nelems,
- kbase_debugfs_helper_set_attr_fn const set_attr_fn)
+int kbase_debugfs_helper_seq_write(
+ struct file *const file, const char __user *const ubuf,
+ size_t const count, size_t const nelems,
+ kbase_debugfs_helper_set_attr_fn *const set_attr_fn)
{
const struct seq_file *const sfile = file->private_data;
void *const array = sfile->private;
@@ -154,6 +212,14 @@ int kbase_debugfs_helper_seq_write(struct file *const file,
}
buf[count] = '\0';
+
+ /* validate string before actually writing values */
+ err = kbase_debugfs_string_validator(buf);
+ if (err) {
+ kfree(buf);
+ return err;
+ }
+
err = set_attr_from_string(buf,
array, nelems, set_attr_fn);
kfree(buf);
@@ -161,9 +227,9 @@ int kbase_debugfs_helper_seq_write(struct file *const file,
return err;
}
-int kbase_debugfs_helper_seq_read(struct seq_file *const sfile,
- size_t const nelems,
- kbase_debugfs_helper_get_attr_fn const get_attr_fn)
+int kbase_debugfs_helper_seq_read(
+ struct seq_file *const sfile, size_t const nelems,
+ kbase_debugfs_helper_get_attr_fn *const get_attr_fn)
{
void *const array = sfile->private;
size_t index;