Avoid segfault if verify header appears longer than io_u
Running this job:
[global]
ioengine=libaio
direct=1
filename=/tmp/foo
iodepth=128
size=10M
loops=1
group_reporting=1
readwrite=write
do_verify=0
verify=md5
numjobs=1
thread
verify_dump=1
[small_writes]
offset=0G
blocksize=512
[large_writes]
offset=1G
blocksize=1M
Followed by this job:
[global]
ioengine=libaio
direct=1
filename=/tmp/foo
iodepth=128
size=1M
loops=1
group_reporting=1
readwrite=read
do_verify=1
verify=md5
verify_fatal=1
numjobs=1
thread
verify_dump=1
bs=4k
[large_reads]
offset=0G
blocksize=1M
[small_reads]
offset=1G
blocksize=512
Will cause a segfault, since the bs=512 job appears to stumble
upon a 1mb header, making fio attempt to verify a much bigger
area than what we have read.
This looks like a zone bug. For now, check in a fix that makes
fio validate the verify header a bit harder.
Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/verify.c b/verify.c
index 5621db2..5fe78c8 100644
--- a/verify.c
+++ b/verify.c
@@ -646,13 +646,17 @@
return ret;
}
-static int verify_header(struct verify_header *hdr)
+static int verify_header(struct io_u *io_u, struct verify_header *hdr)
{
void *p = hdr;
uint32_t crc;
if (hdr->magic != FIO_HDR_MAGIC)
return 0;
+ if (hdr->len > io_u->buflen) {
+ log_err("fio: verify header exceeds buffer length (%u > %lu)\n", hdr->len, io_u->buflen);
+ return 0;
+ }
crc = fio_crc32c(p, offsetof(struct verify_header, crc32));
if (crc == hdr->crc32)
@@ -695,7 +699,7 @@
memswp(p, p + td->o.verify_offset, header_size);
hdr = p;
- if (!verify_header(hdr)) {
+ if (!verify_header(io_u, hdr)) {
log_err("verify: bad magic header %x, wanted %x at "
"file %s offset %llu, length %u\n",
hdr->magic, FIO_HDR_MAGIC,