cpus: Proper range-checking for -icount shift=N

timers_state.icount_time_shift must be in [0,63] to avoid undefined
behavior when shifting by it, e.g. in cpu_icount_to_ns().
icount_adjust() clamps it to [0,MAX_ICOUNT_SHIFT], with
MAX_ICOUNT_SHIFT = 10.  configure_icount() doesn't.  Fix that.

Fixes: a8bfac3708
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20200422130719.28225-5-armbru@redhat.com>
This commit is contained in:
Markus Armbruster 2020-04-22 15:07:09 +02:00
parent abc9bf69a6
commit 9ec374a781

7
cpus.c
View File

@ -25,6 +25,7 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qemu-common.h" #include "qemu-common.h"
#include "qemu/config-file.h" #include "qemu/config-file.h"
#include "qemu/cutils.h"
#include "migration/vmstate.h" #include "migration/vmstate.h"
#include "monitor/monitor.h" #include "monitor/monitor.h"
#include "qapi/error.h" #include "qapi/error.h"
@ -801,7 +802,6 @@ void configure_icount(QemuOpts *opts, Error **errp)
bool sleep = qemu_opt_get_bool(opts, "sleep", true); bool sleep = qemu_opt_get_bool(opts, "sleep", true);
bool align = qemu_opt_get_bool(opts, "align", false); bool align = qemu_opt_get_bool(opts, "align", false);
long time_shift = -1; long time_shift = -1;
char *rem_str = NULL;
if (!option && qemu_opt_get(opts, "align")) { if (!option && qemu_opt_get(opts, "align")) {
error_setg(errp, "Please specify shift option when using align"); error_setg(errp, "Please specify shift option when using align");
@ -814,9 +814,8 @@ void configure_icount(QemuOpts *opts, Error **errp)
} }
if (strcmp(option, "auto") != 0) { if (strcmp(option, "auto") != 0) {
errno = 0; if (qemu_strtol(option, NULL, 0, &time_shift) < 0
time_shift = strtol(option, &rem_str, 0); || time_shift < 0 || time_shift > MAX_ICOUNT_SHIFT) {
if (errno != 0 || *rem_str != '\0' || !strlen(option)) {
error_setg(errp, "icount: Invalid shift value"); error_setg(errp, "icount: Invalid shift value");
return; return;
} }