Google's OSS-fuzz turned up a heap overrun when substituting keywords in
job files. To reproduce compile fio with address sanitizer options like
the following
LDFLAGS="-fsanitize=address" ./configure --disable-optimizations \
--extra-cflags="-fsanitize=address"
The issue is demonstrated by the following job:
% printf '[t]\ndescription=$ncpus_' | fio --parse-only -
opt = 'description=$ncpus'
=================================================================
==22547==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000001863 at pc 0x000107a833c9 bp 0x7ffee82ac260 sp 0x7ffee82ac258
READ of size 1 at 0x603000001863 thread T0
#0 0x107a833c8 in fio_keyword_replace options.c:5124
#1 0x107a7c6ab in dup_and_sub_options options.c:5158
#2 0x107a7bb4f in fio_options_parse options.c:5203
#3 0x1079b2214 in __parse_jobs_ini init.c:2076
#4 0x1079aff07 in parse_jobs_ini init.c:2127
#5 0x1079b7501 in parse_options init.c:2989
#6 0x107b876a4 in main fio.c:42
#7 0x7fff702f1cc8 in start (libdyld.dylib:x86_64+0x1acc8)
Fix the thinko (because opt is pointing to a later position) and
rearrange some code to make it clearer that olen is being used as an
initial offset
Signed-off-by: Sitsofe Wheeler <sitsofe@yahoo.com>
* If there's more in the original string, copy that
* in too
*/
- opt += strlen(kw->word) + olen;
+ opt += olen + strlen(kw->word);
/* keeps final zero thanks to calloc */
if (strlen(opt))
- memcpy(new + olen + len, opt, opt - o_org - 1);
+ memcpy(new + olen + len, opt, strlen(opt));
/*
* replace opt and free the old opt