aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--migration/global_state.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/migration/global_state.c b/migration/global_state.c
index 01805c567a..2c8c447239 100644
--- a/migration/global_state.c
+++ b/migration/global_state.c
@@ -89,6 +89,17 @@ static int global_state_post_load(void *opaque, int version_id)
s->received = true;
trace_migrate_global_state_post_load(runstate);
+ if (strnlen((char *)s->runstate,
+ sizeof(s->runstate)) == sizeof(s->runstate)) {
+ /*
+ * This condition should never happen during migration, because
+ * all runstate names are shorter than 100 bytes (the size of
+ * s->runstate). However, a malicious stream could overflow
+ * the qapi_enum_parse() call, so we force the last character
+ * to a NUL byte.
+ */
+ s->runstate[sizeof(s->runstate) - 1] = '\0';
+ }
r = qapi_enum_parse(&RunState_lookup, runstate, -1, &local_err);
if (r == -1) {
@@ -107,7 +118,8 @@ static int global_state_pre_save(void *opaque)
GlobalState *s = opaque;
trace_migrate_global_state_pre_save((char *)s->runstate);
- s->size = strlen((char *)s->runstate) + 1;
+ s->size = strnlen((char *)s->runstate, sizeof(s->runstate)) + 1;
+ assert(s->size <= sizeof(s->runstate));
return 0;
}