--- sys/vfs/hammer2/hammer2_strategy.c +++ sys/vfs/hammer2/hammer2_strategy.c @@ -207,8 +207,20 @@ kprintf("READ PATH: Error during decompression." "bio %016jx/%d\n", (intmax_t)bio->bio_offset, bytes); - /* make sure it isn't random garbage */ - bzero(compressed_buffer, bp->b_bufsize); + /* + * Fail the buffer (DF-2655): never return fabricated + * data to the caller. Also return early because result + * is negative here, and the tail zero-fill below would + * otherwise compute bp->b_data + result with a negative + * result, an out-of-bounds zeroing of |result| bytes + * BEFORE bp->b_data. + */ + objcache_put(cache_buffer_read, compressed_buffer); + bp->b_flags |= B_ERROR; + bp->b_error = EIO; + bp->b_resid = bp->b_bcount; + bp->b_flags |= B_AGE; + return; } KKASSERT(result <= bp->b_bufsize); bcopy(compressed_buffer, bp->b_data, bp->b_bufsize); @@ -257,7 +269,17 @@ ret = inflate(&strm_decompress, Z_FINISH); if (ret != Z_STREAM_END) { kprintf("HAMMER2 ZLIB: Fatal error during decompression.\n"); - bzero(compressed_buffer, bp->b_bufsize); + /* + * Fail the buffer (DF-2655): never return fabricated + * data to the caller. + */ + objcache_put(cache_buffer_read, compressed_buffer); + inflateEnd(&strm_decompress); + bp->b_flags |= B_ERROR; + bp->b_error = EIO; + bp->b_resid = bp->b_bcount; + bp->b_flags |= B_AGE; + return; } bcopy(compressed_buffer, bp->b_data, bp->b_bufsize); result = bp->b_bufsize - strm_decompress.avail_out;