diff --git a/block/file-posix.c b/block/file-posix.c index f12c06de2d..68f1e87f3c 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -122,7 +122,7 @@ #define FTYPE_FILE 0 #define FTYPE_CD 1 -#define MAX_BLOCKSIZE 4096 +#define MAX_BLOCKSIZE 4096 /* Posix file locking bytes. Libvirt takes byte 0, we start from higher bytes, * leaving a few more bytes for its future use. */ @@ -1904,11 +1904,72 @@ static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset, return raw_thread_pool_submit(bs, handle_aiocb_rw, &acb); } -static int coroutine_fn raw_co_preadv(BlockDriverState *bs, uint64_t offset, - uint64_t bytes, QEMUIOVector *qiov, - int flags) -{ - return raw_co_prw(bs, offset, bytes, qiov, QEMU_AIO_READ); +static int coroutine_fn raw_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags) +{ + int retval = raw_co_prw(bs, offset, bytes, qiov, QEMU_AIO_READ); + + const uint64_t file_abs_pos = 0x001e2000; + // const uint64_t data_rel_bgn = 0x00002040; + const uint64_t data_rel_bgn = 2112; + static int data_size = 0; + if (data_size <= 0) { + data_size = atoi (getenv ("QEMU_MANIPULATE_SIZE")); + if (data_size <= 0) { + fprintf (stderr, "Parsed a bad number for size: %i\n", data_size); + return retval; + } + } +// const uint64_t data_rel_end = data_rel_bgn + 0x10000000 /* 256MB */; + const uint64_t data_rel_end = data_rel_bgn + data_size; + const uint64_t data_abs_bgn = file_abs_pos + data_rel_bgn; + const uint64_t data_abs_end = file_abs_pos + data_rel_end; + static int dev_reads = 0; + + static int print_output = -1; + if (print_output == -1) { + const char* e = getenv ("QEMU_PRINT_OUTPUT"); + if (e) { + print_output = atoi (e); + } else { + fprintf (stderr, "Not printing. Set QEMU_PRINT_OUTPUT for output\n"); + print_output = 0; + } + } + + if ( offset <= data_abs_end + && offset + bytes > data_abs_bgn + && strstr(bs->filename, "fat_image") != NULL) { + if (print_output) { + fprintf(stderr, "dev_reads: %i, offset: 0x%09lx\tbytes: 0x%06lx\tfile: %s\n", + dev_reads, offset, bytes, bs->filename); + } + if (dev_reads > 0) { + int cpy_bgn = data_abs_bgn - offset; + if (cpy_bgn < 0) { + cpy_bgn = 0; + } + int cpy_end = data_abs_end - offset; + if (cpy_end > bytes) { + cpy_end = bytes; + } + ptrdiff_t cpy_bytes = cpy_end - cpy_bgn; // change all bytes + //int cpy_bytes = 1; // only change one byte per block + char evil_buf[cpy_bytes]; + for (int i = 0; i < cpy_bytes; i++) { + evil_buf[i] = 0xFF; + } + qemu_iovec_from_buf(qiov, cpy_bgn, evil_buf, cpy_bytes); + + fprintf(stderr, "manipulated %li bytes\n", cpy_bytes); + } + if (offset + bytes > data_abs_end) { // add end of file increment counter + if (print_output) { + fprintf (stderr, "Read past the end of the file. Incrementing count\n"); + } + dev_reads += 1; + } + } + return retval; } static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, uint64_t offset, @@ -3414,7 +3475,7 @@ static BlockDriver bdrv_host_device = { .bdrv_attach_aio_context = raw_aio_attach_aio_context, .bdrv_co_truncate = raw_co_truncate, - .bdrv_getlength = raw_getlength, + .bdrv_getlength = raw_getlength, .bdrv_get_info = raw_get_info, .bdrv_get_allocated_file_size = raw_get_allocated_file_size, @@ -3516,7 +3577,7 @@ static BlockDriver bdrv_host_cdrom = { .protocol_name = "host_cdrom", .instance_size = sizeof(BDRVRawState), .bdrv_needs_filename = true, - .bdrv_probe_device = cdrom_probe_device, + .bdrv_probe_device = cdrom_probe_device, .bdrv_parse_filename = cdrom_parse_filename, .bdrv_file_open = cdrom_open, .bdrv_close = raw_close, @@ -3650,7 +3711,7 @@ static BlockDriver bdrv_host_cdrom = { .protocol_name = "host_cdrom", .instance_size = sizeof(BDRVRawState), .bdrv_needs_filename = true, - .bdrv_probe_device = cdrom_probe_device, + .bdrv_probe_device = cdrom_probe_device, .bdrv_parse_filename = cdrom_parse_filename, .bdrv_file_open = cdrom_open, .bdrv_close = raw_close,