From 6a5e688425bb394946ef27134aa0f3de928c6a1f Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 26 Jul 2007 10:47:51 +0200 Subject: [PATCH] Fix problem with io_u being beyond EOF Bug report from "ljzhang,Yaxin Hu,Jianchao Tang" : 1. The job file causing the problem: ----------ranmap------------------- [global] directory=./temp nrfiles=1 rw=randread size=64K bsrange=1k-32k thread [ranmap] description="Over-bounded in mark_random_map()." ----------------------------------------- Running the job file, we have a high possibility to get a core dump like this: ---------------------------------------- nonggia@nonggia-desktop:~/fio$ fio --version fio 1.16.9 nonggia@nonggia-desktop:~/fio$ fio ranmap ranmap: (g=0): rw=randread, bs=1K-32K/4K-4K, ioengine=sync, iodepth=1 Starting 1 thread file:io_u.c:64, assert idx < f->num_maps failed Segmentation fault (core dumped) nonggia@nonggia-desktop:~/fio$ gdb fio core.6135 ... ... Core was generated by `fio ranmap'. Program terminated with signal 11, Segmentation fault. io_u.c:64 64 fio_assert(td, idx < f->num_maps); (gdb) bt io_u.c:64 io_u.c:348 io_u.c:588 from /lib/tls/i686/cmov/libpthread.so.0 (gdb) p io_u->offset $1 = 41984 (gdb) p io_u->buflen $2 = 27648 (gdb) p io_u->file->real_file_size $3 = 65536 2. Reason for the core dump: The io_u->offset+io_u->buflen was too large to be map in the map file. They just produced an idx out of the file_map's range. The fix I produced made sure that get_next_buflen() doesn't go beyond the real file size, by shrinking the buflen. Signed-off-by: Jens Axboe --- io_u.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/io_u.c b/io_u.c index 136dc04e..8acc0c39 100644 --- a/io_u.c +++ b/io_u.c @@ -190,6 +190,9 @@ static unsigned int get_next_buflen(struct thread_data *td, struct io_u *io_u) buflen = (buflen + td->o.min_bs[ddir] - 1) & ~(td->o.min_bs[ddir] - 1); } + if (io_u->offset + buflen > io_u->file->real_file_size) + buflen = td->o.min_bs[ddir]; + return buflen; } @@ -341,6 +344,9 @@ static int fill_io_u(struct thread_data *td, struct io_u *io_u) if (!io_u->buflen) return 1; + if (io_u->offset + io_u->buflen > io_u->file->real_file_size) + return 1; + /* * mark entry before potentially trimming io_u */ -- 2.25.1