From 5a4a7d2576ff4af9a526772cf082ddb13e6665fb Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Wed, 2 Aug 2023 12:14:19 +0200 Subject: [PATCH] lib/string_helpers: Introduce parse_int_array() Existing parse_inte_array_user() works with __user buffers only. Separate array parsing from __user bits so the functionality can be utilized with kernel buffers too. Signed-off-by: Cezary Rojewski --- include/linux/string_helpers.h | 1 + lib/string_helpers.c | 39 ++++++++++++++++++---------------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h index 8530c7328269..c623eb16d85a 100644 --- a/include/linux/string_helpers.h +++ b/include/linux/string_helpers.h @@ -21,6 +21,7 @@ enum string_size_units { void string_get_size(u64 size, u64 blk_size, enum string_size_units units, char *buf, int len); +int parse_int_array(const char *buf, size_t count, int **array); int parse_int_array_user(const char __user *from, size_t count, int **array); #define UNESCAPE_SPACE BIT(0) diff --git a/lib/string_helpers.c b/lib/string_helpers.c index 230020a2e076..92c897250fa9 100644 --- a/lib/string_helpers.c +++ b/lib/string_helpers.c @@ -131,6 +131,25 @@ void string_get_size(u64 size, u64 blk_size, const enum string_size_units units, } EXPORT_SYMBOL(string_get_size); +int parse_int_array(const char *buf, size_t count, int **array) +{ + int *ints, nints; + + get_options(buf, 0, &nints); + if (!nints) + return -ENOENT; + + ints = kcalloc(nints + 1, sizeof(*ints), GFP_KERNEL); + if (!ints) + return -ENOMEM; + + get_options(buf, nints + 1, ints); + *array = ints; + + return 0; +} +EXPORT_SYMBOL(parse_int_array); + /** * parse_int_array_user - Split string into a sequence of integers * @from: The user space buffer to read from @@ -146,30 +165,14 @@ EXPORT_SYMBOL(string_get_size); */ int parse_int_array_user(const char __user *from, size_t count, int **array) { - int *ints, nints; char *buf; - int ret = 0; + int ret; buf = memdup_user_nul(from, count); if (IS_ERR(buf)) return PTR_ERR(buf); - get_options(buf, 0, &nints); - if (!nints) { - ret = -ENOENT; - goto free_buf; - } - - ints = kcalloc(nints + 1, sizeof(*ints), GFP_KERNEL); - if (!ints) { - ret = -ENOMEM; - goto free_buf; - } - - get_options(buf, nints + 1, ints); - *array = ints; - -free_buf: + ret = parse_int_array(buf, count, array); kfree(buf); return ret; }