On Sun, 21 Dec 2025 20:26:37 +0800 Li Wang liwang@redhat.com wrote:
write_to_hugetlbfs currently parses the -s size argument with atoi() into an int. This silently accepts malformed input, cannot report overflow, and can truncate large sizes.
And sscanf() will just ignore invalid trailing characters. Probably much the same as atoi() apart from a leading '-'.
Maybe you could use "%zu%c" and check the count is 1 - but I bet some static checker won't like that.
Using strtoul() and checking the terminating character is 'reasonable', but won't detect overflow.
David
--- Error log --- # uname -r 6.12.0-xxx.el10.aarch64+64k
# ls /sys/kernel/mm/hugepages/hugepages-* hugepages-16777216kB/ hugepages-2048kB/ hugepages-524288kB/
#./charge_reserved_hugetlb.sh -cgroup-v2 # ----------------------------------------- ... # nr hugepages = 10 # writing cgroup limit: 5368709120 # writing reseravation limit: 5368709120 ... # Writing to this path: /mnt/huge/test # Writing this size: -1610612736 <--------
Switch the size variable to size_t and parse -s with sscanf("%zu", ...). Also print the size using %zu.
This avoids incorrect behavior with large -s values and makes the utility more robust.
Signed-off-by: Li Wang liwang@redhat.com Cc: David Hildenbrand david@kernel.org Cc: Mark Brown broonie@kernel.org Cc: Shuah Khan shuah@kernel.org Cc: Waiman Long longman@redhat.com Acked-by: David Hildenbrand (Red Hat) david@kernel.org
tools/testing/selftests/mm/write_to_hugetlbfs.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/mm/write_to_hugetlbfs.c b/tools/testing/selftests/mm/write_to_hugetlbfs.c index 34c91f7e6128..ecb5f7619960 100644 --- a/tools/testing/selftests/mm/write_to_hugetlbfs.c +++ b/tools/testing/selftests/mm/write_to_hugetlbfs.c @@ -68,7 +68,7 @@ int main(int argc, char **argv) int key = 0; int *ptr = NULL; int c = 0;
- int size = 0;
- size_t size = 0; char path[256] = ""; enum method method = MAX_METHOD; int want_sleep = 0, private = 0;
@@ -86,7 +86,10 @@ int main(int argc, char **argv) while ((c = getopt(argc, argv, "s:p:m:owlrn")) != -1) { switch (c) { case 's':
size = atoi(optarg);
if (sscanf(optarg, "%zu", &size) != 1) {perror("Invalid -s.");exit_usage(); case 'p': strncpy(path, optarg, sizeof(path) - 1);} break;@@ -131,7 +134,7 @@ int main(int argc, char **argv) } if (size != 0) {
printf("Writing this size: %d\n", size);
} else { errno = EINVAL; perror("size not found");printf("Writing this size: %zu\n", size);