summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block-cow.c3
-rw-r--r--block-qcow.c21
-rw-r--r--block-vpc.c3
-rw-r--r--block.c42
4 files changed, 42 insertions, 27 deletions
diff --git a/block-cow.c b/block-cow.c
index 15270dfd3f..eeeab7068b 100644
--- a/block-cow.c
+++ b/block-cow.c
@@ -54,7 +54,8 @@ static int cow_probe(const uint8_t *buf, int buf_size, const char *filename)
{
const struct cow_header_v2 *cow_header = (const void *)buf;
- if (be32_to_cpu(cow_header->magic) == COW_MAGIC &&
+ if (buf_size >= sizeof(struct cow_header_v2) &&
+ be32_to_cpu(cow_header->magic) == COW_MAGIC &&
be32_to_cpu(cow_header->version) == COW_VERSION)
return 100;
else
diff --git a/block-qcow.c b/block-qcow.c
index a473298a82..ca05be88b0 100644
--- a/block-qcow.c
+++ b/block-qcow.c
@@ -80,8 +80,9 @@ static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset);
static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
{
const QCowHeader *cow_header = (const void *)buf;
-
- if (be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
+
+ if (buf_size >= sizeof(QCowHeader) &&
+ be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
be32_to_cpu(cow_header->version) == QCOW_VERSION)
return 100;
else
@@ -551,9 +552,19 @@ static int qcow_create(const char *filename, int64_t total_size,
header_size = sizeof(header);
backing_filename_len = 0;
if (backing_file) {
- realpath(backing_file, backing_filename);
- if (stat(backing_filename, &st) != 0) {
- return -1;
+ const char *p;
+ /* XXX: this is a hack: we do not attempt to check for URL
+ like syntax */
+ p = strchr(backing_file, ':');
+ if (p && (p - backing_file) >= 2) {
+ /* URL like but exclude "c:" like filenames */
+ pstrcpy(backing_filename, sizeof(backing_filename),
+ backing_file);
+ } else {
+ realpath(backing_file, backing_filename);
+ if (stat(backing_filename, &st) != 0) {
+ return -1;
+ }
}
header.mtime = cpu_to_be32(st.st_mtime);
header.backing_file_offset = cpu_to_be64(header_size);
diff --git a/block-vpc.c b/block-vpc.c
index 88ad575bf8..e4c51bab2a 100644
--- a/block-vpc.c
+++ b/block-vpc.c
@@ -81,9 +81,8 @@ typedef struct BDRVVPCState {
static int vpc_probe(const uint8_t *buf, int buf_size, const char *filename)
{
- if (!strncmp(buf, "conectix", 8))
+ if (buf_size >= 8 && !strncmp(buf, "conectix", 8))
return 100;
-
return 0;
}
diff --git a/block.c b/block.c
index 8baa3b87e2..18eaf46041 100644
--- a/block.c
+++ b/block.c
@@ -106,26 +106,29 @@ static BlockDriver *find_image_format(const char *filename)
size_t bufsize = 1024;
fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
- if (fd < 0)
- return NULL;
+ if (fd < 0) {
+ buf = NULL;
+ ret = 0;
+ } else {
#ifdef DIOCGSECTORSIZE
- {
- unsigned int sectorsize = 512;
- if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
- sectorsize > bufsize)
- bufsize = sectorsize;
- }
+ {
+ unsigned int sectorsize = 512;
+ if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
+ sectorsize > bufsize)
+ bufsize = sectorsize;
+ }
#endif
- buf = malloc(bufsize);
- if (!buf)
- return NULL;
- ret = read(fd, buf, bufsize);
- if (ret < 0) {
+ buf = qemu_malloc(bufsize);
+ if (!buf)
+ return NULL;
+ ret = read(fd, buf, bufsize);
+ if (ret < 0) {
+ close(fd);
+ qemu_free(buf);
+ return NULL;
+ }
close(fd);
- free(buf);
- return NULL;
}
- close(fd);
drv = NULL;
score_max = 0;
@@ -136,7 +139,7 @@ static BlockDriver *find_image_format(const char *filename)
drv = drv1;
}
}
- free(buf);
+ qemu_free(buf);
return drv;
}
@@ -154,7 +157,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int snapshot,
bs->read_only = 0;
bs->is_temporary = 0;
bs->encrypted = 0;
-
+
if (snapshot) {
BlockDriverState *bs1;
int64_t total_size;
@@ -183,7 +186,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int snapshot,
filename = tmp_filename;
bs->is_temporary = 1;
}
-
+
pstrcpy(bs->filename, sizeof(bs->filename), filename);
if (!drv) {
drv = find_image_format(filename);
@@ -653,4 +656,5 @@ void bdrv_init(void)
bdrv_register(&bdrv_dmg);
bdrv_register(&bdrv_bochs);
bdrv_register(&bdrv_vpc);
+ bdrv_register(&bdrv_vvfat);
}