From cf00f975d506d20ad5f02ee9dd8fec17af74bb2f Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sat, 22 Oct 2011 18:47:21 +0200 Subject: [PATCH] Fix io_u->buf calculation overflow Jagadish reports: ---- following are the details of the bug in fio. This bug in fio can show up as corruption of data when performing verify. Description: ---------------- if the product of block size and queudepth is greater than 4GB, io_u buffer will not be assigned properly due to overflow. fio --bsrange=256k-4m --ioengine=libaio --iodepth=2064 --direct=1 --name=job3 --offset=2GB --size=14GB --rw=write --verify_pattern=0xdeadbeef --filename=/dev/sdb can show false corruption. Version: ----------- 1.58 Explanation: ----------------- in a loop fio tries to assign the data buffer to each i/o request. static int init_io_u(struct thread_data *td) { struct io_u *io_u; unsigned int max_bs; int cl_align, i, max_units; char *p; ... p = td->orig_buffer; ... for (i = 0; i < max_units; i++) { ... io_u->buf = p + max_bs * i; } } at max_bs=4M i=1024, the integer overflows and the addresses are being used again. i,e i/o request 1024 will have the same data buffer as that of i/o request 0. This is seen from fio debug log. mem 11164 io_u alloc 0x219f530, index 0 mem 11164 io_u 0x219f530, mem 0x7f09bb62d000 mem 11164 io_u alloc 0x219f820, index 1 mem 11164 io_u 0x219f820, mem 0x7f09bba2d000 mem 11164 io_u alloc 0x225b530, index 1024 mem 11164 io_u 0x225b530, mem 0x7f09bb62d000 mem 11164 io_u alloc 0x225b820, index 1025 mem 11164 io_u 0x225b820, mem 0x7f09bba2d000 the fix is as follows: io_u->buf = p + (unsigned long long)max_bs * i; ---- Fix this by continually incrementing 'p' instead, avoiding the overflow as well. Reported-by: Jagadish Kumar Signed-off-by: Jens Axboe --- fio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fio.c b/fio.c index c18df12d..5b58ab82 100644 --- a/fio.c +++ b/fio.c @@ -936,7 +936,7 @@ static int init_io_u(struct thread_data *td) dprint(FD_MEM, "io_u alloc %p, index %u\n", io_u, i); if (!(td->io_ops->flags & FIO_NOIO)) { - io_u->buf = p + max_bs * i; + io_u->buf = p; dprint(FD_MEM, "io_u %p, mem %p\n", io_u, io_u->buf); if (td_write(td)) @@ -953,6 +953,7 @@ static int init_io_u(struct thread_data *td) io_u->index = i; io_u->flags = IO_U_F_FREE; flist_add(&io_u->list, &td->io_u_freelist); + p += max_bs; } return 0; -- 2.25.1