Block patches:

- Added NULL checks found by static analysis
 - Allow more block drivers to not be included in the qemu build
 -----BEGIN PGP SIGNATURE-----
 
 iQEcBAABAgAGBQJb6a+GAAoJEPQH2wBh1c9ATAEH/iIa6f5a2rvNfnzpMjFqbHhg
 GMCLqVm10EkphyD3t/99MuyU1OFYkaObojV5wv085cOtyKLvZdVDtmlmKO2XAvdt
 w209B+8wlWTGqG4+FObopmgrq5VBMgNNlZ3WqDxkGFKCBI9w7QSv7upTLqTg9P2O
 /3dnhBDfFLgGZhlXhmtZaPhAW51j1B4mpeXKX1KXIDkMEYMoMA8MZoPx3v72gO2E
 V51i/MMUJwNjynlNn/Dyf/9pjmyzZLliZmkTqKpa8DPBaGjQ4/Fe4aGxqXUgv0Uz
 pXLAeL0tYZaLxHrguJltrovavJx13OjYm9Vq5W5Zq1PmhLTA+uBXJmHMzUxBHYg=
 =N/Mn
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'mreitz/tags/pull-block-2018-11-12' into queue-block

Block patches:
- Added NULL checks found by static analysis
- Allow more block drivers to not be included in the qemu build

# gpg: Signature made Mon Nov 12 17:51:18 2018 CET
# gpg:                using RSA key F407DB0061D5CF40
# gpg: Good signature from "Max Reitz <mreitz@redhat.com>"
# Primary key fingerprint: 91BE B60A 30DB 3E88 57D1  1829 F407 DB00 61D5 CF40

* mreitz/tags/pull-block-2018-11-12:
  qcow2: Read outside array bounds in qcow2_pre_write_overlap_check()
  block: Fix potential Null pointer dereferences in vvfat.c
  qemu-img: assert block_job_get() does not return NULL in img_commit()
  block: Null pointer dereference in blk_root_get_parent_desc()
  job: Fix off-by-one assert checks for JobSTT and JobVerbTable
  block: Make more block drivers compile-time configurable

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Kevin Wolf 2018-11-12 17:57:32 +01:00
commit 1a42e5d829
7 changed files with 152 additions and 33 deletions

View File

@ -1,10 +1,18 @@
block-obj-y += raw-format.o qcow.o vdi.o vmdk.o cloop.o bochs.o vpc.o vvfat.o dmg.o
block-obj-y += raw-format.o vmdk.o vpc.o
block-obj-$(CONFIG_QCOW1) += qcow.o
block-obj-$(CONFIG_VDI) += vdi.o
block-obj-$(CONFIG_CLOOP) += cloop.o
block-obj-$(CONFIG_BOCHS) += bochs.o
block-obj-$(CONFIG_VVFAT) += vvfat.o
block-obj-$(CONFIG_DMG) += dmg.o
block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o qcow2-bitmap.o
block-obj-y += qed.o qed-l2-cache.o qed-table.o qed-cluster.o
block-obj-y += qed-check.o
block-obj-$(CONFIG_QED) += qed.o qed-l2-cache.o qed-table.o qed-cluster.o
block-obj-$(CONFIG_QED) += qed-check.o
block-obj-y += vhdx.o vhdx-endian.o vhdx-log.o
block-obj-y += quorum.o
block-obj-y += parallels.o blkdebug.o blkverify.o blkreplay.o
block-obj-y += blkdebug.o blkverify.o blkreplay.o
block-obj-$(CONFIG_PARALLELS) += parallels.o
block-obj-y += blklogwrites.o
block-obj-y += block-backend.o snapshot.o qapi.o
block-obj-$(CONFIG_WIN32) += file-win32.o win32-aio.o
@ -14,7 +22,8 @@ block-obj-y += null.o mirror.o commit.o io.o create.o
block-obj-y += throttle-groups.o
block-obj-$(CONFIG_LINUX) += nvme.o
block-obj-y += nbd.o nbd-client.o sheepdog.o
block-obj-y += nbd.o nbd-client.o
block-obj-$(CONFIG_SHEEPDOG) += sheepdog.o
block-obj-$(CONFIG_LIBISCSI) += iscsi.o
block-obj-$(if $(CONFIG_LIBISCSI),y,n) += iscsi-opts.o
block-obj-$(CONFIG_LIBNFS) += nfs.o
@ -45,7 +54,8 @@ gluster.o-libs := $(GLUSTERFS_LIBS)
vxhs.o-libs := $(VXHS_LIBS)
ssh.o-cflags := $(LIBSSH2_CFLAGS)
ssh.o-libs := $(LIBSSH2_LIBS)
block-obj-$(if $(CONFIG_BZIP2),m,n) += dmg-bz2.o
block-obj-dmg-bz2-$(CONFIG_BZIP2) += dmg-bz2.o
block-obj-$(if $(CONFIG_DMG),m,n) += $(block-obj-dmg-bz2-y)
dmg-bz2.o-libs := $(BZIP2_LIBS)
qcow.o-libs := -lz
linux-aio.o-libs := -laio

View File

@ -918,7 +918,8 @@ char *blk_get_attached_dev_id(BlockBackend *blk)
} else if (dev->id) {
return g_strdup(dev->id);
}
return object_get_canonical_path(OBJECT(dev));
return object_get_canonical_path(OBJECT(dev)) ?: g_strdup("");
}
/*

View File

@ -2719,15 +2719,17 @@ int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
}
static const char *metadata_ol_names[] = {
[QCOW2_OL_MAIN_HEADER_BITNR] = "qcow2_header",
[QCOW2_OL_ACTIVE_L1_BITNR] = "active L1 table",
[QCOW2_OL_ACTIVE_L2_BITNR] = "active L2 table",
[QCOW2_OL_REFCOUNT_TABLE_BITNR] = "refcount table",
[QCOW2_OL_REFCOUNT_BLOCK_BITNR] = "refcount block",
[QCOW2_OL_SNAPSHOT_TABLE_BITNR] = "snapshot table",
[QCOW2_OL_INACTIVE_L1_BITNR] = "inactive L1 table",
[QCOW2_OL_INACTIVE_L2_BITNR] = "inactive L2 table",
[QCOW2_OL_MAIN_HEADER_BITNR] = "qcow2_header",
[QCOW2_OL_ACTIVE_L1_BITNR] = "active L1 table",
[QCOW2_OL_ACTIVE_L2_BITNR] = "active L2 table",
[QCOW2_OL_REFCOUNT_TABLE_BITNR] = "refcount table",
[QCOW2_OL_REFCOUNT_BLOCK_BITNR] = "refcount block",
[QCOW2_OL_SNAPSHOT_TABLE_BITNR] = "snapshot table",
[QCOW2_OL_INACTIVE_L1_BITNR] = "inactive L1 table",
[QCOW2_OL_INACTIVE_L2_BITNR] = "inactive L2 table",
[QCOW2_OL_BITMAP_DIRECTORY_BITNR] = "bitmap directory",
};
QEMU_BUILD_BUG_ON(QCOW2_OL_MAX_BITNR != ARRAY_SIZE(metadata_ol_names));
/*
* First performs a check for metadata overlaps (through

View File

@ -100,30 +100,26 @@ static inline void array_free(array_t* array)
/* does not automatically grow */
static inline void* array_get(array_t* array,unsigned int index) {
assert(index < array->next);
assert(array->pointer);
return array->pointer + index * array->item_size;
}
static inline int array_ensure_allocated(array_t* array, int index)
static inline void array_ensure_allocated(array_t *array, int index)
{
if((index + 1) * array->item_size > array->size) {
int new_size = (index + 32) * array->item_size;
array->pointer = g_realloc(array->pointer, new_size);
if (!array->pointer)
return -1;
assert(array->pointer);
memset(array->pointer + array->size, 0, new_size - array->size);
array->size = new_size;
array->next = index + 1;
}
return 0;
}
static inline void* array_get_next(array_t* array) {
unsigned int next = array->next;
if (array_ensure_allocated(array, next) < 0)
return NULL;
array_ensure_allocated(array, next);
array->next = next + 1;
return array_get(array, next);
}
@ -2422,16 +2418,13 @@ static int commit_direntries(BDRVVVFATState* s,
direntry_t* direntry = array_get(&(s->directory), dir_index);
uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry);
mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
int factor = 0x10 * s->sectors_per_cluster;
int old_cluster_count, new_cluster_count;
int current_dir_index = mapping->info.dir.first_dir_index;
int first_dir_index = current_dir_index;
int current_dir_index;
int first_dir_index;
int ret, i;
uint32_t c;
DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapping->path, parent_mapping_index));
assert(direntry);
assert(mapping);
assert(mapping->begin == first_cluster);
@ -2439,6 +2432,11 @@ DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapp
assert(mapping->mode & MODE_DIRECTORY);
assert(dir_index == 0 || is_directory(direntry));
DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n",
mapping->path, parent_mapping_index));
current_dir_index = mapping->info.dir.first_dir_index;
first_dir_index = current_dir_index;
mapping->info.dir.parent_mapping_index = parent_mapping_index;
if (first_cluster == 0) {
@ -2488,6 +2486,9 @@ DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapp
direntry = array_get(&(s->directory), first_dir_index + i);
if (is_directory(direntry) && !is_dot(direntry)) {
mapping = find_mapping_for_cluster(s, first_cluster);
if (mapping == NULL) {
return -1;
}
assert(mapping->mode & MODE_DIRECTORY);
ret = commit_direntries(s, first_dir_index + i,
array_index(&(s->mapping), mapping));
@ -2516,6 +2517,10 @@ static int commit_one_file(BDRVVVFATState* s,
assert(offset < size);
assert((offset % s->cluster_size) == 0);
if (mapping == NULL) {
return -1;
}
for (i = s->cluster_size; i < offset; i += s->cluster_size)
c = modified_fat_get(s, c);
@ -2662,8 +2667,12 @@ static int handle_renames_and_mkdirs(BDRVVVFATState* s)
if (commit->action == ACTION_RENAME) {
mapping_t* mapping = find_mapping_for_cluster(s,
commit->param.rename.cluster);
char* old_path = mapping->path;
char *old_path;
if (mapping == NULL) {
return -1;
}
old_path = mapping->path;
assert(commit->path);
mapping->path = commit->path;
if (rename(old_path, mapping->path))
@ -2684,10 +2693,15 @@ static int handle_renames_and_mkdirs(BDRVVVFATState* s)
direntry_t* d = direntry + i;
if (is_file(d) || (is_directory(d) && !is_dot(d))) {
int l;
char *new_path;
mapping_t* m = find_mapping_for_cluster(s,
begin_of_direntry(d));
int l = strlen(m->path);
char* new_path = g_malloc(l + diff + 1);
if (m == NULL) {
return -1;
}
l = strlen(m->path);
new_path = g_malloc(l + diff + 1);
assert(!strncmp(m->path, mapping->path, l2));

91
configure vendored
View File

@ -470,6 +470,15 @@ tcmalloc="no"
jemalloc="no"
replication="yes"
vxhs=""
bochs="yes"
cloop="yes"
dmg="yes"
qcow1="yes"
vdi="yes"
vvfat="yes"
qed="yes"
parallels="yes"
sheepdog="yes"
libxml2=""
docker="no"
debug_mutex="no"
@ -1416,6 +1425,42 @@ for opt do
;;
--enable-vxhs) vxhs="yes"
;;
--disable-bochs) bochs="no"
;;
--enable-bochs) bochs="yes"
;;
--disable-cloop) cloop="no"
;;
--enable-cloop) cloop="yes"
;;
--disable-dmg) dmg="no"
;;
--enable-dmg) dmg="yes"
;;
--disable-qcow1) qcow1="no"
;;
--enable-qcow1) qcow1="yes"
;;
--disable-vdi) vdi="no"
;;
--enable-vdi) vdi="yes"
;;
--disable-vvfat) vvfat="no"
;;
--enable-vvfat) vvfat="yes"
;;
--disable-qed) qed="no"
;;
--enable-qed) qed="yes"
;;
--disable-parallels) parallels="no"
;;
--enable-parallels) parallels="yes"
;;
--disable-sheepdog) sheepdog="no"
;;
--enable-sheepdog) sheepdog="yes"
;;
--disable-vhost-user) vhost_user="no"
;;
--enable-vhost-user)
@ -1718,6 +1763,15 @@ disabled with --disable-FEATURE, default is enabled if available:
qom-cast-debug cast debugging support
tools build qemu-io, qemu-nbd and qemu-image tools
vxhs Veritas HyperScale vDisk backend support
bochs bochs image format support
cloop cloop image format support
dmg dmg image format support
qcow1 qcow v1 image format support
vdi vdi image format support
vvfat vvfat image format support
qed qed image format support
parallels parallels image format support
sheepdog sheepdog block driver support
crypto-afalg Linux AF_ALG crypto backend driver
vhost-user vhost-user support
capstone capstone disassembler support
@ -6043,6 +6097,15 @@ echo "jemalloc support $jemalloc"
echo "avx2 optimization $avx2_opt"
echo "replication support $replication"
echo "VxHS block device $vxhs"
echo "bochs support $bochs"
echo "cloop support $cloop"
echo "dmg support $dmg"
echo "qcow v1 support $qcow1"
echo "vdi support $vdi"
echo "vvfat support $vvfat"
echo "qed support $qed"
echo "parallels support $parallels"
echo "sheepdog support $sheepdog"
echo "capstone $capstone"
echo "docker $docker"
echo "libpmem support $libpmem"
@ -6799,6 +6862,34 @@ if test "$libpmem" = "yes" ; then
echo "CONFIG_LIBPMEM=y" >> $config_host_mak
fi
if test "$bochs" = "yes" ; then
echo "CONFIG_BOCHS=y" >> $config_host_mak
fi
if test "$cloop" = "yes" ; then
echo "CONFIG_CLOOP=y" >> $config_host_mak
fi
if test "$dmg" = "yes" ; then
echo "CONFIG_DMG=y" >> $config_host_mak
fi
if test "$qcow1" = "yes" ; then
echo "CONFIG_QCOW1=y" >> $config_host_mak
fi
if test "$vdi" = "yes" ; then
echo "CONFIG_VDI=y" >> $config_host_mak
fi
if test "$vvfat" = "yes" ; then
echo "CONFIG_VVFAT=y" >> $config_host_mak
fi
if test "$qed" = "yes" ; then
echo "CONFIG_QED=y" >> $config_host_mak
fi
if test "$parallels" = "yes" ; then
echo "CONFIG_PARALLELS=y" >> $config_host_mak
fi
if test "$sheepdog" = "yes" ; then
echo "CONFIG_SHEEPDOG=y" >> $config_host_mak
fi
if test "$tcg_interpreter" = "yes"; then
QEMU_INCLUDES="-iquote \$(SRC_PATH)/tcg/tci $QEMU_INCLUDES"
elif test "$ARCH" = "sparc64" ; then

4
job.c
View File

@ -159,7 +159,7 @@ bool job_is_internal(Job *job)
static void job_state_transition(Job *job, JobStatus s1)
{
JobStatus s0 = job->status;
assert(s1 >= 0 && s1 <= JOB_STATUS__MAX);
assert(s1 >= 0 && s1 < JOB_STATUS__MAX);
trace_job_state_transition(job, job->ret,
JobSTT[s0][s1] ? "allowed" : "disallowed",
JobStatus_str(s0), JobStatus_str(s1));
@ -174,7 +174,7 @@ static void job_state_transition(Job *job, JobStatus s1)
int job_apply_verb(Job *job, JobVerb verb, Error **errp)
{
JobStatus s0 = job->status;
assert(verb >= 0 && verb <= JOB_VERB__MAX);
assert(verb >= 0 && verb < JOB_VERB__MAX);
trace_job_apply_verb(job, JobStatus_str(s0), JobVerb_str(verb),
JobVerbTable[verb][s0] ? "allowed" : "prohibited");
if (JobVerbTable[verb][s0]) {

View File

@ -1029,6 +1029,7 @@ static int img_commit(int argc, char **argv)
}
job = block_job_get("commit");
assert(job);
run_block_job(job, &local_err);
if (local_err) {
goto unref_backing;