From 2e0a52594ed11e738d2402a3e22d05ec5597535a Mon Sep 17 00:00:00 2001 From: aggieNick02 Date: Fri, 1 Sep 2023 17:01:05 -0500 Subject: [PATCH] Add basic error checking to parsing nr from rw=randrw:, etc Previously this was parsed by just doing atoi(). This returns 0 or has undefined behavior in error cases. Silently getting a 0 for nr is not great. In fact, 0 (or less) should likely not be allowed for nr; while the code handles it, the effective result is that the randomness is gone - all I/O becomes sequential. It makes sense to prohibit 0 as an nr value in the random case. We leverage str_to_decimal to do our parsing instead of atoi. It isn't perfect, but it is a lot more resilient than atoi, and used in other similar places. We can then return an error when parsing fails, and also return an error when the parsed numeric value is outside of the ranges that can be stored in the unsigned int used for nr, along with when nr is 0. Fixes #1622 Signed-off-by: Nick Neumann nick@pcpartpicker.com --- options.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/options.c b/options.c index 48aa0d7b1c..65b2813c27 100644 --- a/options.c +++ b/options.c @@ -596,9 +596,21 @@ static int str_rw_cb(void *data, const char *str) if (!nr) return 0; - if (td_random(td)) - o->ddir_seq_nr = atoi(nr); - else { + if (td_random(td)) { + long long val; + + if (str_to_decimal(nr, &val, 1, o, 0, 0)) { + log_err("fio: randrw postfix parsing failed\n"); + free(nr); + return 1; + } + if ((val <= 0) || (val > UINT_MAX)) { + log_err("fio: randrw postfix parsing out of range\n"); + free(nr); + return 1; + } + o->ddir_seq_nr = (unsigned int) val; + } else { long long val; if (str_to_decimal(nr, &val, 1, o, 0, 0)) {