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 += 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-$(CONFIG_QED) += qed.o qed-l2-cache.o qed-table.o qed-cluster.o
block-obj-y += qed-check.o block-obj-$(CONFIG_QED) += qed-check.o
block-obj-y += vhdx.o vhdx-endian.o vhdx-log.o block-obj-y += vhdx.o vhdx-endian.o vhdx-log.o
block-obj-y += quorum.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 += blklogwrites.o
block-obj-y += block-backend.o snapshot.o qapi.o block-obj-y += block-backend.o snapshot.o qapi.o
block-obj-$(CONFIG_WIN32) += file-win32.o win32-aio.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-y += throttle-groups.o
block-obj-$(CONFIG_LINUX) += nvme.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-$(CONFIG_LIBISCSI) += iscsi.o
block-obj-$(if $(CONFIG_LIBISCSI),y,n) += iscsi-opts.o block-obj-$(if $(CONFIG_LIBISCSI),y,n) += iscsi-opts.o
block-obj-$(CONFIG_LIBNFS) += nfs.o block-obj-$(CONFIG_LIBNFS) += nfs.o
@ -45,7 +54,8 @@ gluster.o-libs := $(GLUSTERFS_LIBS)
vxhs.o-libs := $(VXHS_LIBS) vxhs.o-libs := $(VXHS_LIBS)
ssh.o-cflags := $(LIBSSH2_CFLAGS) ssh.o-cflags := $(LIBSSH2_CFLAGS)
ssh.o-libs := $(LIBSSH2_LIBS) 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) dmg-bz2.o-libs := $(BZIP2_LIBS)
qcow.o-libs := -lz qcow.o-libs := -lz
linux-aio.o-libs := -laio linux-aio.o-libs := -laio

View File

@ -918,7 +918,8 @@ char *blk_get_attached_dev_id(BlockBackend *blk)
} else if (dev->id) { } else if (dev->id) {
return g_strdup(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

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

91
configure vendored
View File

@ -470,6 +470,15 @@ tcmalloc="no"
jemalloc="no" jemalloc="no"
replication="yes" replication="yes"
vxhs="" vxhs=""
bochs="yes"
cloop="yes"
dmg="yes"
qcow1="yes"
vdi="yes"
vvfat="yes"
qed="yes"
parallels="yes"
sheepdog="yes"
libxml2="" libxml2=""
docker="no" docker="no"
debug_mutex="no" debug_mutex="no"
@ -1416,6 +1425,42 @@ for opt do
;; ;;
--enable-vxhs) vxhs="yes" --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" --disable-vhost-user) vhost_user="no"
;; ;;
--enable-vhost-user) --enable-vhost-user)
@ -1718,6 +1763,15 @@ disabled with --disable-FEATURE, default is enabled if available:
qom-cast-debug cast debugging support qom-cast-debug cast debugging support
tools build qemu-io, qemu-nbd and qemu-image tools tools build qemu-io, qemu-nbd and qemu-image tools
vxhs Veritas HyperScale vDisk backend support 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 crypto-afalg Linux AF_ALG crypto backend driver
vhost-user vhost-user support vhost-user vhost-user support
capstone capstone disassembler support capstone capstone disassembler support
@ -6043,6 +6097,15 @@ echo "jemalloc support $jemalloc"
echo "avx2 optimization $avx2_opt" echo "avx2 optimization $avx2_opt"
echo "replication support $replication" echo "replication support $replication"
echo "VxHS block device $vxhs" 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 "capstone $capstone"
echo "docker $docker" echo "docker $docker"
echo "libpmem support $libpmem" echo "libpmem support $libpmem"
@ -6799,6 +6862,34 @@ if test "$libpmem" = "yes" ; then
echo "CONFIG_LIBPMEM=y" >> $config_host_mak echo "CONFIG_LIBPMEM=y" >> $config_host_mak
fi 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 if test "$tcg_interpreter" = "yes"; then
QEMU_INCLUDES="-iquote \$(SRC_PATH)/tcg/tci $QEMU_INCLUDES" QEMU_INCLUDES="-iquote \$(SRC_PATH)/tcg/tci $QEMU_INCLUDES"
elif test "$ARCH" = "sparc64" ; then 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) static void job_state_transition(Job *job, JobStatus s1)
{ {
JobStatus s0 = job->status; 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, trace_job_state_transition(job, job->ret,
JobSTT[s0][s1] ? "allowed" : "disallowed", JobSTT[s0][s1] ? "allowed" : "disallowed",
JobStatus_str(s0), JobStatus_str(s1)); 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) int job_apply_verb(Job *job, JobVerb verb, Error **errp)
{ {
JobStatus s0 = job->status; 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), trace_job_apply_verb(job, JobStatus_str(s0), JobVerb_str(verb),
JobVerbTable[verb][s0] ? "allowed" : "prohibited"); JobVerbTable[verb][s0] ? "allowed" : "prohibited");
if (JobVerbTable[verb][s0]) { if (JobVerbTable[verb][s0]) {

View File

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