* [Qemu-devel] [PATCH v2 1/8] configure: Provide option to explicitly disable AVX2
2018-08-31 16:36 [Qemu-devel] [PATCH v2 0/8] off-by-one and NULL pointer accesses detected by static analysis Liam Merwick
@ 2018-08-31 16:36 ` Liam Merwick
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 2/8] job: Fix off-by-one assert checks for JobSTT and JobVerbTable Liam Merwick
` (6 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Liam Merwick @ 2018-08-31 16:36 UTC (permalink / raw)
To: qemu-devel
The configure script detects if the compiler has AVX2 support and
automatically sets avx2_opt="yes" which in turn defines CONFIG_AVX2_OPT.
There is no way of explicitly overriding this setting so this commit adds
two command-line options: --enable-avx2 and --disable-avx2.
The default behaviour, when no option is specified, is to maintain the
current behaviour and enable AVX2 if the compiler supports it.
Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com>
Reviewed-by: Darren Kenny <Darren.Kenny@oracle.com>
Reviewed-by: Mark Kanda <Mark.Kanda@oracle.com>
---
configure | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/configure b/configure
index 58862d2ae88a..8904a91715b3 100755
--- a/configure
+++ b/configure
@@ -427,7 +427,7 @@ usb_redir=""
opengl=""
opengl_dmabuf="no"
cpuid_h="no"
-avx2_opt="no"
+avx2_opt=""
zlib="yes"
capstone=""
lzo=""
@@ -1332,6 +1332,10 @@ for opt do
;;
--disable-glusterfs) glusterfs="no"
;;
+ --disable-avx2) avx2_opt="no"
+ ;;
+ --enable-avx2) avx2_opt="yes"
+ ;;
--enable-glusterfs) glusterfs="yes"
;;
--disable-virtio-blk-data-plane|--enable-virtio-blk-data-plane)
@@ -1709,6 +1713,7 @@ disabled with --disable-FEATURE, default is enabled if available:
libxml2 for Parallels image format
tcmalloc tcmalloc support
jemalloc jemalloc support
+ avx2 AVX2 optimization support
replication replication support
vhost-vsock virtio sockets device support
opengl opengl support
@@ -5127,7 +5132,7 @@ fi
# There is no point enabling this if cpuid.h is not usable,
# since we won't be able to select the new routines.
-if test $cpuid_h = yes; then
+if test "$cpuid_h" = "yes" -a "$avx2_opt" != "no"; then
cat > $TMPC << EOF
#pragma GCC push_options
#pragma GCC target("avx2")
@@ -5141,6 +5146,8 @@ int main(int argc, char *argv[]) { return bar(argv[0]); }
EOF
if compile_object "" ; then
avx2_opt="yes"
+ else
+ avx2_opt="no"
fi
fi
--
1.8.3.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v2 2/8] job: Fix off-by-one assert checks for JobSTT and JobVerbTable
2018-08-31 16:36 [Qemu-devel] [PATCH v2 0/8] off-by-one and NULL pointer accesses detected by static analysis Liam Merwick
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 1/8] configure: Provide option to explicitly disable AVX2 Liam Merwick
@ 2018-08-31 16:36 ` Liam Merwick
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 3/8] block: Null pointer dereference in blk_root_get_parent_desc() Liam Merwick
` (5 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Liam Merwick @ 2018-08-31 16:36 UTC (permalink / raw)
To: qemu-devel
In the assert checking the array dereference of JobVerbTable[verb]
in job_apply_verb() the check of the index, verb, allows an overrun
because an index equal to the array size is permitted.
Similarly, in the assert check of JobSTT[s0][s1] with index s1
in job_state_transition(), an off-by-one overrun is not flagged
either.
This is not a run-time issue as there are no callers actually
passing in the max value.
Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com>
Reviewed-by: Darren Kenny <Darren.Kenny@oracle.com>
Reviewed-by: Mark Kanda <Mark.Kanda@oracle.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
job.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/job.c b/job.c
index e36ebaafd81c..40320566f43b 100644
--- a/job.c
+++ b/job.c
@@ -166,7 +166,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));
@@ -181,7 +181,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]) {
--
1.8.3.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v2 3/8] block: Null pointer dereference in blk_root_get_parent_desc()
2018-08-31 16:36 [Qemu-devel] [PATCH v2 0/8] off-by-one and NULL pointer accesses detected by static analysis Liam Merwick
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 1/8] configure: Provide option to explicitly disable AVX2 Liam Merwick
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 2/8] job: Fix off-by-one assert checks for JobSTT and JobVerbTable Liam Merwick
@ 2018-08-31 16:36 ` Liam Merwick
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 4/8] qemu-img: potential Null pointer deref in img_commit() Liam Merwick
` (4 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Liam Merwick @ 2018-08-31 16:36 UTC (permalink / raw)
To: qemu-devel
The dev_id returned by the call to blk_get_attached_dev_id() in
blk_root_get_parent_desc() can be NULL (an internal call to
object_get_canonical_path may have returned NULL) so it should
be checked before dereferencing.
Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com>
Reviewed-by: Darren Kenny <Darren.Kenny@oracle.com>
Reviewed-by: Mark Kanda <Mark.Kanda@oracle.com>
---
block/block-backend.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index fa120630be83..210eee75006a 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -136,7 +136,7 @@ static char *blk_root_get_parent_desc(BdrvChild *child)
}
dev_id = blk_get_attached_dev_id(blk);
- if (*dev_id) {
+ if (dev_id && *dev_id) {
return dev_id;
} else {
/* TODO Callback into the BB owner for something more detailed */
--
1.8.3.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v2 4/8] qemu-img: potential Null pointer deref in img_commit()
2018-08-31 16:36 [Qemu-devel] [PATCH v2 0/8] off-by-one and NULL pointer accesses detected by static analysis Liam Merwick
` (2 preceding siblings ...)
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 3/8] block: Null pointer dereference in blk_root_get_parent_desc() Liam Merwick
@ 2018-08-31 16:36 ` Liam Merwick
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 5/8] block: Fix potential Null pointer dereferences in vvfat.c Liam Merwick
` (3 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Liam Merwick @ 2018-08-31 16:36 UTC (permalink / raw)
To: qemu-devel
The function block_job_get() may return NULL so before dereferencing
the 'job' pointer in img_commit() it should be checked.
Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com>
Reviewed-by: Darren Kenny <Darren.Kenny@oracle.com>
Reviewed-by: Mark Kanda <Mark.Kanda@oracle.com>
---
qemu-img.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/qemu-img.c b/qemu-img.c
index b12f4cd19b0a..51fe09bd08ed 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1029,6 +1029,9 @@ static int img_commit(int argc, char **argv)
}
job = block_job_get("commit");
+ if (job == NULL) {
+ goto unref_backing;
+ }
run_block_job(job, &local_err);
if (local_err) {
goto unref_backing;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v2 5/8] block: Fix potential Null pointer dereferences in vvfat.c
2018-08-31 16:36 [Qemu-devel] [PATCH v2 0/8] off-by-one and NULL pointer accesses detected by static analysis Liam Merwick
` (3 preceding siblings ...)
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 4/8] qemu-img: potential Null pointer deref in img_commit() Liam Merwick
@ 2018-08-31 16:36 ` Liam Merwick
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 6/8] block: dump_qlist() may dereference a Null pointer Liam Merwick
` (2 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Liam Merwick @ 2018-08-31 16:36 UTC (permalink / raw)
To: qemu-devel
The calls to bdrv_new_open_driver(), find_mapping_for_cluster(),
and array_get_next() may return NULL but it isn't always checked for
before dereferencing the value returned.
Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com>
Reviewed-by: Darren Kenny <Darren.Kenny@oracle.com>
Reviewed-by: Mark Kanda <Mark.Kanda@oracle.com>
---
block/vvfat.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/block/vvfat.c b/block/vvfat.c
index fc41841a5c3c..0f1f10a2f94b 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -448,6 +448,9 @@ static direntry_t *create_long_filename(BDRVVVFATState *s, const char *filename)
for(i=0;i<number_of_entries;i++) {
entry=array_get_next(&(s->directory));
+ if (entry == NULL) {
+ continue;
+ }
entry->attributes=0xf;
entry->reserved[0]=0;
entry->begin=0;
@@ -665,6 +668,9 @@ static inline void fat_set(BDRVVVFATState* s,unsigned int cluster,uint32_t value
} else {
int offset = (cluster*3/2);
unsigned char* p = array_get(&(s->fat), offset);
+ if (p == NULL) {
+ return;
+ }
switch (cluster&1) {
case 0:
p[0] = value&0xff;
@@ -730,6 +736,9 @@ static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
if(is_dot) {
entry=array_get_next(&(s->directory));
+ if (entry == NULL) {
+ return NULL;
+ }
memset(entry->name, 0x20, sizeof(entry->name));
memcpy(entry->name,filename,strlen(filename));
return entry;
@@ -844,6 +853,12 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
/* create mapping for this file */
if(!is_dot && !is_dotdot && (S_ISDIR(st.st_mode) || st.st_size)) {
s->current_mapping = array_get_next(&(s->mapping));
+ if (s->current_mapping == NULL) {
+ fprintf(stderr, "Failed to create mapping for file\n");
+ g_free(buffer);
+ closedir(dir);
+ return -2;
+ }
s->current_mapping->begin=0;
s->current_mapping->end=st.st_size;
/*
@@ -941,6 +956,9 @@ static int init_directories(BDRVVVFATState* s,
/* add volume label */
{
direntry_t* entry=array_get_next(&(s->directory));
+ if (entry == NULL) {
+ return -1;
+ }
entry->attributes=0x28; /* archive | volume label */
memcpy(entry->name, s->volume_label, sizeof(entry->name));
}
@@ -953,6 +971,9 @@ static int init_directories(BDRVVVFATState* s,
s->cluster_count=sector2cluster(s, s->sector_count);
mapping = array_get_next(&(s->mapping));
+ if (mapping == NULL) {
+ return -1;
+ }
mapping->begin = 0;
mapping->dir_index = 0;
mapping->info.dir.parent_mapping_index = -1;
@@ -1630,6 +1651,9 @@ static void schedule_rename(BDRVVVFATState* s,
uint32_t cluster, char* new_path)
{
commit_t* commit = array_get_next(&(s->commits));
+ if (commit == NULL) {
+ return;
+ }
commit->path = new_path;
commit->param.rename.cluster = cluster;
commit->action = ACTION_RENAME;
@@ -1639,6 +1663,9 @@ static void schedule_writeout(BDRVVVFATState* s,
int dir_index, uint32_t modified_offset)
{
commit_t* commit = array_get_next(&(s->commits));
+ if (commit == NULL) {
+ return;
+ }
commit->path = NULL;
commit->param.writeout.dir_index = dir_index;
commit->param.writeout.modified_offset = modified_offset;
@@ -1649,6 +1676,9 @@ static void schedule_new_file(BDRVVVFATState* s,
char* path, uint32_t first_cluster)
{
commit_t* commit = array_get_next(&(s->commits));
+ if (commit == NULL) {
+ return;
+ }
commit->path = path;
commit->param.new_file.first_cluster = first_cluster;
commit->action = ACTION_NEW_FILE;
@@ -1657,6 +1687,9 @@ static void schedule_new_file(BDRVVVFATState* s,
static void schedule_mkdir(BDRVVVFATState* s, uint32_t cluster, char* path)
{
commit_t* commit = array_get_next(&(s->commits));
+ if (commit == NULL) {
+ return;
+ }
commit->path = path;
commit->param.mkdir.cluster = cluster;
commit->action = ACTION_MKDIR;
@@ -2261,6 +2294,9 @@ static mapping_t* insert_mapping(BDRVVVFATState* s,
}
if (index >= s->mapping.next || mapping->begin > begin) {
mapping = array_insert(&(s->mapping), index, 1);
+ if (mapping == NULL) {
+ return NULL;
+ }
mapping->path = NULL;
adjust_mapping_indices(s, index, +1);
}
@@ -2428,6 +2464,9 @@ 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);
+ if (mapping == NULL) {
+ return -1;
+ }
int factor = 0x10 * s->sectors_per_cluster;
int old_cluster_count, new_cluster_count;
@@ -2494,6 +2533,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));
@@ -2522,6 +2564,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);
@@ -2668,6 +2714,9 @@ 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);
+ if (mapping == NULL) {
+ return -1;
+ }
char* old_path = mapping->path;
assert(commit->path);
@@ -2692,6 +2741,9 @@ static int handle_renames_and_mkdirs(BDRVVVFATState* s)
if (is_file(d) || (is_directory(d) && !is_dot(d))) {
mapping_t* m = find_mapping_for_cluster(s,
begin_of_direntry(d));
+ if (m == NULL) {
+ return -3;
+ }
int l = strlen(m->path);
char* new_path = g_malloc(l + diff + 1);
@@ -3193,6 +3245,10 @@ static int enable_write_target(BlockDriverState *bs, Error **errp)
backing = bdrv_new_open_driver(&vvfat_write_target, NULL, BDRV_O_ALLOW_RDWR,
&error_abort);
+ if (!backing) {
+ ret = -EINVAL;
+ goto err;
+ }
*(void**) backing->opaque = s;
bdrv_set_backing_hd(s->bs, backing, &error_abort);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v2 6/8] block: dump_qlist() may dereference a Null pointer
2018-08-31 16:36 [Qemu-devel] [PATCH v2 0/8] off-by-one and NULL pointer accesses detected by static analysis Liam Merwick
` (4 preceding siblings ...)
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 5/8] block: Fix potential Null pointer dereferences in vvfat.c Liam Merwick
@ 2018-08-31 16:36 ` Liam Merwick
2018-08-31 16:47 ` Eric Blake
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 7/8] io: potential unnecessary check in qio_channel_command_new_spawn() Liam Merwick
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 8/8] qcow2: Read outside array bounds in qcow2_pre_write_overlap_check() Liam Merwick
7 siblings, 1 reply; 13+ messages in thread
From: Liam Merwick @ 2018-08-31 16:36 UTC (permalink / raw)
To: qemu-devel
A NULL 'list' passed into function dump_qlist() isn't correctly
validated and can be passed to qlist_first() where it is dereferenced.
Given that dump_qlist() is static, and callers already do the right
thing, just add an assert to catch future potential bugs.
Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com>
---
block/qapi.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/block/qapi.c b/block/qapi.c
index c66f949db839..e81be604217c 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -740,6 +740,8 @@ static void dump_qlist(fprintf_function func_fprintf, void *f, int indentation,
const QListEntry *entry;
int i = 0;
+ assert(list);
+
for (entry = qlist_first(list); entry; entry = qlist_next(entry), i++) {
QType type = qobject_type(entry->value);
bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH v2 6/8] block: dump_qlist() may dereference a Null pointer
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 6/8] block: dump_qlist() may dereference a Null pointer Liam Merwick
@ 2018-08-31 16:47 ` Eric Blake
0 siblings, 0 replies; 13+ messages in thread
From: Eric Blake @ 2018-08-31 16:47 UTC (permalink / raw)
To: Liam Merwick, qemu-devel
On 08/31/2018 11:36 AM, Liam Merwick wrote:
> A NULL 'list' passed into function dump_qlist() isn't correctly
> validated and can be passed to qlist_first() where it is dereferenced.
>
> Given that dump_qlist() is static, and callers already do the right
Double space looks odd.
> thing, just add an assert to catch future potential bugs.
>
> Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com>
> ---
> block/qapi.c | 2 ++
> 1 file changed, 2 insertions(+)
Reviewed-by: Eric Blake <eblake@redhat.com>
>
> diff --git a/block/qapi.c b/block/qapi.c
> index c66f949db839..e81be604217c 100644
> --- a/block/qapi.c
> +++ b/block/qapi.c
> @@ -740,6 +740,8 @@ static void dump_qlist(fprintf_function func_fprintf, void *f, int indentation,
> const QListEntry *entry;
> int i = 0;
>
> + assert(list);
> +
> for (entry = qlist_first(list); entry; entry = qlist_next(entry), i++) {
> QType type = qobject_type(entry->value);
> bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST);
>
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v2 7/8] io: potential unnecessary check in qio_channel_command_new_spawn()
2018-08-31 16:36 [Qemu-devel] [PATCH v2 0/8] off-by-one and NULL pointer accesses detected by static analysis Liam Merwick
` (5 preceding siblings ...)
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 6/8] block: dump_qlist() may dereference a Null pointer Liam Merwick
@ 2018-08-31 16:36 ` Liam Merwick
2018-08-31 16:48 ` Eric Blake
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 8/8] qcow2: Read outside array bounds in qcow2_pre_write_overlap_check() Liam Merwick
7 siblings, 1 reply; 13+ messages in thread
From: Liam Merwick @ 2018-08-31 16:36 UTC (permalink / raw)
To: qemu-devel
In qio_channel_command_new_spawn() the 'flags' variable is checked
to see if /dev/null should be used for stdin or stdout; first with
O_RDONLY and then O_WRONLY. However the second check for O_WRONLY
is only needed if flags != O_RDONLY and therefore should be an
else if statement.
This minor optimization has the added benefit of suppressing a warning
from a static analysis tool (Parfait) which incorrectly reported an
incorrect checking of flags in qio_channel_command_new_spawn() could
result in an uninitialized file descriptor being used. Removing this
noise will help us better find real issues.
Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com>
---
io/channel-command.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/io/channel-command.c b/io/channel-command.c
index 3e7eb17eff54..82acd3234915 100644
--- a/io/channel-command.c
+++ b/io/channel-command.c
@@ -61,8 +61,7 @@ qio_channel_command_new_spawn(const char *const argv[],
if (flags == O_RDONLY) {
stdinnull = true;
- }
- if (flags == O_WRONLY) {
+ } else if (flags == O_WRONLY) {
stdoutnull = true;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH v2 7/8] io: potential unnecessary check in qio_channel_command_new_spawn()
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 7/8] io: potential unnecessary check in qio_channel_command_new_spawn() Liam Merwick
@ 2018-08-31 16:48 ` Eric Blake
0 siblings, 0 replies; 13+ messages in thread
From: Eric Blake @ 2018-08-31 16:48 UTC (permalink / raw)
To: Liam Merwick, qemu-devel
On 08/31/2018 11:36 AM, Liam Merwick wrote:
> In qio_channel_command_new_spawn() the 'flags' variable is checked
> to see if /dev/null should be used for stdin or stdout; first with
> O_RDONLY and then O_WRONLY. However the second check for O_WRONLY
> is only needed if flags != O_RDONLY and therefore should be an
> else if statement.
>
> This minor optimization has the added benefit of suppressing a warning
> from a static analysis tool (Parfait) which incorrectly reported an
> incorrect checking of flags in qio_channel_command_new_spawn() could
> result in an uninitialized file descriptor being used. Removing this
> noise will help us better find real issues.
>
> Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com>
> ---
> io/channel-command.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
Reviewed-by: Eric Blake <eblake@redhat.com>
>
> diff --git a/io/channel-command.c b/io/channel-command.c
> index 3e7eb17eff54..82acd3234915 100644
> --- a/io/channel-command.c
> +++ b/io/channel-command.c
> @@ -61,8 +61,7 @@ qio_channel_command_new_spawn(const char *const argv[],
>
> if (flags == O_RDONLY) {
> stdinnull = true;
> - }
> - if (flags == O_WRONLY) {
> + } else if (flags == O_WRONLY) {
> stdoutnull = true;
> }
>
>
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [PATCH v2 8/8] qcow2: Read outside array bounds in qcow2_pre_write_overlap_check()
2018-08-31 16:36 [Qemu-devel] [PATCH v2 0/8] off-by-one and NULL pointer accesses detected by static analysis Liam Merwick
` (6 preceding siblings ...)
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 7/8] io: potential unnecessary check in qio_channel_command_new_spawn() Liam Merwick
@ 2018-08-31 16:36 ` Liam Merwick
2018-08-31 16:53 ` Eric Blake
7 siblings, 1 reply; 13+ messages in thread
From: Liam Merwick @ 2018-08-31 16:36 UTC (permalink / raw)
To: qemu-devel
The commit for 0e4e4318eaa5 increments QCOW2_OL_MAX_BITNR but does not
add an array entry for QCOW2_OL_BITMAP_DIRECTORY_BITNR to metadata_ol_names[].
As a result, an array dereference of metadata_ol_names[8] in
qcow2_pre_write_overlap_check() could result in a read outside of the array bounds.
Fixes: 0e4e4318eaa5 ('qcow2: add overlap check for bitmap directory')
Cc: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com>
---
block/qcow2-refcount.c | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 3c539f02e5ec..fb0de187cfd2 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -2719,16 +2719,26 @@ 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",
};
+
+/*
+ * Catch at compile time the case where an overlap detection bit
+ * was added to QCow2MetadataOverlap in block/qcow2.h but a
+ * corresponding entry to metadata_ol_names[] wasn't added.
+ */
+QEMU_BUILD_BUG_ON(QCOW2_OL_MAX_BITNR !=
+ (sizeof(metadata_ol_names) / sizeof(metadata_ol_names[0])));
+
/*
* First performs a check for metadata overlaps (through
* qcow2_check_metadata_overlap); if that fails with a negative value (error
--
1.8.3.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH v2 8/8] qcow2: Read outside array bounds in qcow2_pre_write_overlap_check()
2018-08-31 16:36 ` [Qemu-devel] [PATCH v2 8/8] qcow2: Read outside array bounds in qcow2_pre_write_overlap_check() Liam Merwick
@ 2018-08-31 16:53 ` Eric Blake
2018-08-31 18:16 ` Liam Merwick
0 siblings, 1 reply; 13+ messages in thread
From: Eric Blake @ 2018-08-31 16:53 UTC (permalink / raw)
To: Liam Merwick, qemu-devel
On 08/31/2018 11:36 AM, Liam Merwick wrote:
> The commit for 0e4e4318eaa5 increments QCOW2_OL_MAX_BITNR but does not
> add an array entry for QCOW2_OL_BITMAP_DIRECTORY_BITNR to metadata_ol_names[].
> As a result, an array dereference of metadata_ol_names[8] in
> qcow2_pre_write_overlap_check() could result in a read outside of the array bounds.
>
> Fixes: 0e4e4318eaa5 ('qcow2: add overlap check for bitmap directory')
>
> Cc: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
> Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com>
> ---
> block/qcow2-refcount.c | 26 ++++++++++++++++++--------
> 1 file changed, 18 insertions(+), 8 deletions(-)
>
> +
> +/*
> + * Catch at compile time the case where an overlap detection bit
> + * was added to QCow2MetadataOverlap in block/qcow2.h but a
> + * corresponding entry to metadata_ol_names[] wasn't added.
> + */
I'm not sure the comment adds much value. I'd be fine with dropping it.
> +QEMU_BUILD_BUG_ON(QCOW2_OL_MAX_BITNR !=
> + (sizeof(metadata_ol_names) / sizeof(metadata_ol_names[0])));
We have a macro for that. Spell this:
QEMU_BUILD_BUG_ON(QCOW2_OL_MAX_BITNR != ARRAY_SIZE(metadata_ol_names));
and then you can have
Reviewed-by: Eric Blake <eblake@redhat.com>
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization: qemu.org | libvirt.org
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [PATCH v2 8/8] qcow2: Read outside array bounds in qcow2_pre_write_overlap_check()
2018-08-31 16:53 ` Eric Blake
@ 2018-08-31 18:16 ` Liam Merwick
0 siblings, 0 replies; 13+ messages in thread
From: Liam Merwick @ 2018-08-31 18:16 UTC (permalink / raw)
To: Eric Blake, qemu-devel
On 31/08/18 17:53, Eric Blake wrote:
> On 08/31/2018 11:36 AM, Liam Merwick wrote:
>> The commit for 0e4e4318eaa5 increments QCOW2_OL_MAX_BITNR but does not
>> add an array entry for QCOW2_OL_BITMAP_DIRECTORY_BITNR to
>> metadata_ol_names[].
>> As a result, an array dereference of metadata_ol_names[8] in
>> qcow2_pre_write_overlap_check() could result in a read outside of the
>> array bounds.
>>
>> Fixes: 0e4e4318eaa5 ('qcow2: add overlap check for bitmap directory')
>>
>> Cc: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
>> Signed-off-by: Liam Merwick <Liam.Merwick@oracle.com>
>> ---
>> block/qcow2-refcount.c | 26 ++++++++++++++++++--------
>> 1 file changed, 18 insertions(+), 8 deletions(-)
>>
>
>> +
>> +/*
>> + * Catch at compile time the case where an overlap detection bit
>> + * was added to QCow2MetadataOverlap in block/qcow2.h but a
>> + * corresponding entry to metadata_ol_names[] wasn't added.
>> + */
>
> I'm not sure the comment adds much value. I'd be fine with dropping it.
>
>> +QEMU_BUILD_BUG_ON(QCOW2_OL_MAX_BITNR !=
>> + (sizeof(metadata_ol_names) / sizeof(metadata_ol_names[0])));
>
> We have a macro for that. Spell this:
>
> QEMU_BUILD_BUG_ON(QCOW2_OL_MAX_BITNR != ARRAY_SIZE(metadata_ol_names));
>
> and then you can have
>
> Reviewed-by: Eric Blake <eblake@redhat.com>
>
Thanks, I've updated those and removed the double space in patch6. Will
be in upcoming v3
Regards,
Liam
^ permalink raw reply [flat|nested] 13+ messages in thread