From: Eric Biggers <ebiggers@xxxxxxxxxx> Fix a weird bug in mread where if you passed it a length that was 1 modulo the page size, for example xfs_io -r file -c "mmap -r 0 8192" -c "mread -v 0 4097" ... it never reset its pointer into the buffer into which it copies the data from the memory map. This caused an out-of-bounds write, which depending on the length passed could be very large and reliably segfault. Also nothing was printed, despite the use of -v option. (I don't know if this case gets reached by any existing xfstest, but presumably not. I noticed it while working on a patch to an xfstest.) Signed-off-by: Eric Biggers <ebiggers@xxxxxxxxxx> --- io/mmap.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/io/mmap.c b/io/mmap.c index 85087f57..4c03e3d5 100644 --- a/io/mmap.c +++ b/io/mmap.c @@ -469,38 +469,30 @@ mread_f( dumplen = length % pagesize; if (!dumplen) dumplen = pagesize; if (rflag) { - for (tmp = length - 1, c = 0; tmp >= 0; tmp--, c = 1) { - *bp = *(((char *)mapping->addr) + dumpoffset + tmp); - cnt++; - if (c && cnt == dumplen) { + for (tmp = length - 1; tmp >= 0; tmp--) { + bp[cnt++] = ((char *)mapping->addr)[dumpoffset + tmp]; + if (cnt == dumplen) { if (dump) { dump_buffer(printoffset, dumplen); printoffset += dumplen; } - bp = (char *)io_buffer; dumplen = pagesize; cnt = 0; - } else { - bp++; } } } else { - for (tmp = 0, c = 0; tmp < length; tmp++, c = 1) { - *bp = *(((char *)mapping->addr) + dumpoffset + tmp); - cnt++; - if (c && cnt == dumplen) { + for (tmp = 0; tmp < length; tmp++) { + bp[cnt++] = ((char *)mapping->addr)[dumpoffset + tmp]; + if (cnt == dumplen) { if (dump) dump_buffer(printoffset + tmp - (dumplen - 1), dumplen); - bp = (char *)io_buffer; dumplen = pagesize; cnt = 0; - } else { - bp++; } } } return 0; } base-commit: df4bd2d27189a98711fd35965c18bee25a25a9ea -- 2.45.1