From c076de85fa4901683f6ce23ecdc071c17801ffad Mon Sep 17 00:00:00 2001 From: Sitsofe Wheeler Date: Thu, 21 Dec 2017 12:23:36 +0000 Subject: [PATCH] eta: fix buffer overflow in ETA output When 900 or more jobs all have different states it is possible for the space required to display the ETA line to be larger than the ETA output buffer. fio initially truncates what it puts in the output buffer but incorrectly advances where it thinks the end of the buffer is - when truncating snprintf returns the number of characters that _would_ have been converted if there had been enough space... This patch fixes the post truncation calculation and adjusts the "left" variable so there is room for the carriage return and a null terminator. The following script reproduces the problem when fio has been compiled with -fstack-protector or -fsanitize=address: rw[0]='read'; rw[1]='write'; \ for i in {1..1000}; do \ echo -e "[job$i]\nrw=${rw[$((i % 2))]}\n" \ "ramp_time=$(((1000 - i) / 350 * 5))\n" \ "runtime=$((60 - (i % 3) * 2))"; \ done | \ ./fio --eta-newline=1s --group_reporting --ioengine=null --size=1g \ --time_based --bs=512 --thread --rate_iops=123456 - Fixes: https://github.com/axboe/fio/issues/500 ("Large number of threads result in Seg faults") Signed-off-by: Sitsofe Wheeler --- eta.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/eta.c b/eta.c index 8b77dafa..087f57d9 100644 --- a/eta.c +++ b/eta.c @@ -585,7 +585,7 @@ void display_thread_status(struct jobs_eta *je) iops_str[ddir] = num2str(je->iops[ddir], 4, 1, 0, N2S_NONE); } - left = sizeof(output) - (p - output) - 1; + left = sizeof(output) - (p - output) - 2; if (je->rate[DDIR_TRIM] || je->iops[DDIR_TRIM]) l = snprintf(p, left, @@ -601,6 +601,8 @@ void display_thread_status(struct jobs_eta *je) rate_str[DDIR_READ], rate_str[DDIR_WRITE], iops_str[DDIR_READ], iops_str[DDIR_WRITE], eta_str); + if (l > left) + l = left; p += l; if (l >= 0 && l < linelen_last) p += sprintf(p, "%*s", linelen_last - l, ""); -- 2.25.1