diff -rup qemu-kvm-0.15.1/block/vvfat.c frob/block/vvfat.c --- qemu-kvm-0.15.1/block/vvfat.c 2012-07-29 20:56:28.318227757 -0400 +++ frob/block/vvfat.c 2012-07-29 20:59:15.537859208 -0400 @@ -2795,7 +2795,12 @@ static int enable_write_target(BDRVVVFAT array_init(&(s->commits), sizeof(commit_t)); s->qcow_filename = qemu_malloc(1024); - get_tmp_filename(s->qcow_filename, 1024); + ret = get_tmp_filename(s->qcow_filename, 1024); + if (ret < 0) { + free(s->qcow_filename); + s->qcow_filename = NULL; + return ret; + } bdrv_qcow = bdrv_find_format("qcow"); options = parse_option_parameters("", bdrv_qcow->create_options, NULL); diff -rup qemu-kvm-0.15.1/block.c frob/block.c --- qemu-kvm-0.15.1/block.c 2012-07-29 20:56:28.367221495 -0400 +++ frob/block.c 2012-07-29 20:58:24.931326050 -0400 @@ -254,28 +254,36 @@ int bdrv_create_file(const char* filenam return bdrv_create(drv, filename, options); } -#ifdef _WIN32 -void get_tmp_filename(char *filename, int size) +/* + * Create a uniquely-named empty temporary file. + * Return 0 upon success, otherwise a negative errno value. + */ +int get_tmp_filename(char *filename, int size) { +#ifdef _WIN32 char temp_dir[MAX_PATH]; - - GetTempPath(MAX_PATH, temp_dir); - GetTempFileName(temp_dir, "qem", 0, filename); -} + /* GetTempFileName requires that its output buffer (4th param) + have length MAX_PATH or greater. */ + assert(size >= MAX_PATH); + return (GetTempPath(MAX_PATH, temp_dir) + && GetTempFileName(temp_dir, "qem", 0, filename) + ? 0 : -GetLastError()); #else -void get_tmp_filename(char *filename, int size) -{ int fd; const char *tmpdir; - /* XXX: race condition possible */ tmpdir = getenv("TMPDIR"); if (!tmpdir) tmpdir = "/tmp"; - snprintf(filename, size, "%s/vl.XXXXXX", tmpdir); + if (snprintf(filename, size, "%s/vl.XXXXXX", tmpdir) >= size) { + return -EOVERFLOW; + } fd = mkstemp(filename); - close(fd); -} + if (fd < 0 || close(fd)) { + return -errno; + } + return 0; #endif +} /* * Detect host devices. By convention, /dev/cdrom[N] is always @@ -555,7 +563,10 @@ int bdrv_open(BlockDriverState *bs, cons bdrv_delete(bs1); - get_tmp_filename(tmp_filename, sizeof(tmp_filename)); + ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename)); + if (ret < 0) { + return ret; + } /* Real path is meaningless for protocols */ if (is_protocol) diff -rup qemu-kvm-0.15.1/block_int.h frob/block_int.h --- qemu-kvm-0.15.1/block_int.h 2011-10-19 09:54:48.000000000 -0400 +++ frob/block_int.h 2012-07-29 20:58:24.932325925 -0400 @@ -216,7 +216,7 @@ struct BlockDriverAIOCB { BlockDriverAIOCB *next; }; -void get_tmp_filename(char *filename, int size); +int get_tmp_filename(char *filename, int size); void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque);