* [PATCH 0/2] migration: Fix possible access out of bounds @ 2025-07-15 12:45 Fabiano Rosas 2025-07-15 12:45 ` [PATCH 1/2] migration: Fix postcopy latency distribution formatting computation Fabiano Rosas 2025-07-15 12:45 ` [PATCH 2/2] cutils: Add time_us_to_str Fabiano Rosas 0 siblings, 2 replies; 10+ messages in thread From: Fabiano Rosas @ 2025-07-15 12:45 UTC (permalink / raw) To: qemu-devel; +Cc: Peter Xu, Philippe Mathieu-Daudé, Peter Maydell Fix the issue detected by Coverity in format_time_str() and move the function into the generic utils as suggested. Fabiano Rosas (2): migration: Fix postcopy latency distribution formatting computation cutils: Add time_us_to_str include/qemu/cutils.h | 1 + migration/migration-hmp-cmds.c | 19 ++----------------- util/cutils.c | 13 +++++++++++++ 3 files changed, 16 insertions(+), 17 deletions(-) -- 2.35.3 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/2] migration: Fix postcopy latency distribution formatting computation 2025-07-15 12:45 [PATCH 0/2] migration: Fix possible access out of bounds Fabiano Rosas @ 2025-07-15 12:45 ` Fabiano Rosas 2025-07-15 14:01 ` Philippe Mathieu-Daudé ` (2 more replies) 2025-07-15 12:45 ` [PATCH 2/2] cutils: Add time_us_to_str Fabiano Rosas 1 sibling, 3 replies; 10+ messages in thread From: Fabiano Rosas @ 2025-07-15 12:45 UTC (permalink / raw) To: qemu-devel; +Cc: Peter Xu, Philippe Mathieu-Daudé, Peter Maydell Coverity has caught a bug in the formatting of time intervals for postcopy latency distribution display in 'info migrate'. While bounds checking the labels array, sizeof is incorrectly being used. ARRAY_SIZE is the correct form of obtaining the size of an array. Fixes: 3345fb3b6d ("migration/postcopy: Add latency distribution report for blocktime") Resolves: Coverity CID 1612248 Suggested-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Fabiano Rosas <farosas@suse.de> --- migration/migration-hmp-cmds.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c index cef5608210..bb954881d7 100644 --- a/migration/migration-hmp-cmds.c +++ b/migration/migration-hmp-cmds.c @@ -57,11 +57,9 @@ static const gchar *format_time_str(uint64_t us) const char *units[] = {"us", "ms", "sec"}; int index = 0; - while (us > 1000) { + while (us > 1000 && index + 1 < ARRAY_SIZE(units)) { us /= 1000; - if (++index >= (sizeof(units) - 1)) { - break; - } + index++; } return g_strdup_printf("%"PRIu64" %s", us, units[index]); -- 2.35.3 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] migration: Fix postcopy latency distribution formatting computation 2025-07-15 12:45 ` [PATCH 1/2] migration: Fix postcopy latency distribution formatting computation Fabiano Rosas @ 2025-07-15 14:01 ` Philippe Mathieu-Daudé 2025-07-16 10:26 ` Prasad Pandit 2025-07-17 13:31 ` Daniel P. Berrangé 2 siblings, 0 replies; 10+ messages in thread From: Philippe Mathieu-Daudé @ 2025-07-15 14:01 UTC (permalink / raw) To: Fabiano Rosas, qemu-devel; +Cc: Peter Xu, Peter Maydell On 15/7/25 14:45, Fabiano Rosas wrote: > Coverity has caught a bug in the formatting of time intervals for > postcopy latency distribution display in 'info migrate'. > > While bounds checking the labels array, sizeof is incorrectly being > used. ARRAY_SIZE is the correct form of obtaining the size of an > array. > > Fixes: 3345fb3b6d ("migration/postcopy: Add latency distribution report for blocktime") > Resolves: Coverity CID 1612248 > Suggested-by: Peter Maydell <peter.maydell@linaro.org> > Signed-off-by: Fabiano Rosas <farosas@suse.de> > --- > migration/migration-hmp-cmds.c | 6 ++---- > 1 file changed, 2 insertions(+), 4 deletions(-) Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] migration: Fix postcopy latency distribution formatting computation 2025-07-15 12:45 ` [PATCH 1/2] migration: Fix postcopy latency distribution formatting computation Fabiano Rosas 2025-07-15 14:01 ` Philippe Mathieu-Daudé @ 2025-07-16 10:26 ` Prasad Pandit 2025-07-16 13:36 ` Fabiano Rosas 2025-07-17 13:31 ` Daniel P. Berrangé 2 siblings, 1 reply; 10+ messages in thread From: Prasad Pandit @ 2025-07-16 10:26 UTC (permalink / raw) To: Fabiano Rosas Cc: qemu-devel, Peter Xu, Philippe Mathieu-Daudé, Peter Maydell On Tue, 15 Jul 2025 at 18:49, Fabiano Rosas <farosas@suse.de> wrote: > @@ -57,11 +57,9 @@ static const gchar *format_time_str(uint64_t us) > const char *units[] = {"us", "ms", "sec"}; > int index = 0; > > - while (us > 1000) { > + while (us > 1000 && index + 1 < ARRAY_SIZE(units)) { > us /= 1000; > - if (++index >= (sizeof(units) - 1)) { > - break; > - } > + index++; > } > > return g_strdup_printf("%"PRIu64" %s", us, units[index]); * This loop is rather confusing. * Is the while loop converting microseconds (us) to seconds with: us /= 1000 ? ie. index shall mostly be 2 = "sec", except for the range = 1000000 - 1000999, when us / 1000 => 1000 would break the while loop and it'd return string "1000 ms". === #define MS (1000) #define US (MS * 1000) #define NS (US * 1000) if (n >= NS) n /= NS; else if (n >= US) n /= US; else if (n >= MS) n /= MS; return g_strdup_printf("%"PRIu64" sec", n); === * Does the above simplification look right? It shall always return seconds as: "<n> sec" Thank you. --- - Prasad ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] migration: Fix postcopy latency distribution formatting computation 2025-07-16 10:26 ` Prasad Pandit @ 2025-07-16 13:36 ` Fabiano Rosas 2025-07-17 6:28 ` Prasad Pandit 0 siblings, 1 reply; 10+ messages in thread From: Fabiano Rosas @ 2025-07-16 13:36 UTC (permalink / raw) To: Prasad Pandit Cc: qemu-devel, Peter Xu, Philippe Mathieu-Daudé, Peter Maydell Prasad Pandit <ppandit@redhat.com> writes: > On Tue, 15 Jul 2025 at 18:49, Fabiano Rosas <farosas@suse.de> wrote: >> @@ -57,11 +57,9 @@ static const gchar *format_time_str(uint64_t us) >> const char *units[] = {"us", "ms", "sec"}; >> int index = 0; >> >> - while (us > 1000) { >> + while (us > 1000 && index + 1 < ARRAY_SIZE(units)) { >> us /= 1000; >> - if (++index >= (sizeof(units) - 1)) { >> - break; >> - } >> + index++; >> } >> >> return g_strdup_printf("%"PRIu64" %s", us, units[index]); > > * This loop is rather confusing. > > * Is the while loop converting microseconds (us) to seconds with: us > /= 1000 ? ie. index shall mostly be 2 = "sec", except for the range = > 1000000 - 1000999, when us / 1000 => 1000 would break the while loop > and it'd return string "1000 ms". Good catch. The condition should be >=. > === > #define MS (1000) > #define US (MS * 1000) > #define NS (US * 1000) > > if (n >= NS) > n /= NS; > else if (n >= US) > n /= US; > else if (n >= MS) > n /= MS; > > return g_strdup_printf("%"PRIu64" sec", n); > === > > * Does the above simplification look right? It shall always return > seconds as: "<n> sec" > But then that's "0 sec" for 1000000 us. > > Thank you. > --- > - Prasad ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] migration: Fix postcopy latency distribution formatting computation 2025-07-16 13:36 ` Fabiano Rosas @ 2025-07-17 6:28 ` Prasad Pandit 2025-07-17 12:35 ` Fabiano Rosas 0 siblings, 1 reply; 10+ messages in thread From: Prasad Pandit @ 2025-07-17 6:28 UTC (permalink / raw) To: Fabiano Rosas Cc: qemu-devel, Peter Xu, Philippe Mathieu-Daudé, Peter Maydell On Wed, 16 Jul 2025 at 19:06, Fabiano Rosas <farosas@suse.de> wrote: > The condition should be >=. * I'm thinking of doing away with the loop and the string array. The array has 3 values of which only one gets used due to conversion to seconds. > But then that's "0 sec" for 1000000 us. #define US (MS * 1000) => 1000000 When us = 1000000, us / US should return "1 sec", no? Thank you. --- - Prasad ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] migration: Fix postcopy latency distribution formatting computation 2025-07-17 6:28 ` Prasad Pandit @ 2025-07-17 12:35 ` Fabiano Rosas 0 siblings, 0 replies; 10+ messages in thread From: Fabiano Rosas @ 2025-07-17 12:35 UTC (permalink / raw) To: Prasad Pandit Cc: qemu-devel, Peter Xu, Philippe Mathieu-Daudé, Peter Maydell Prasad Pandit <ppandit@redhat.com> writes: > On Wed, 16 Jul 2025 at 19:06, Fabiano Rosas <farosas@suse.de> wrote: >> The condition should be >=. > > * I'm thinking of doing away with the loop and the string array. The > array has 3 values of which only one gets used due to conversion to > seconds. The point is not to convert to seconds, but to fit the number of microseconds in a range. Take a look at the output of 'info migrate -a' with postcopy-blocktime capability enabled. > >> But then that's "0 sec" for 1000000 us. > > #define US (MS * 1000) => 1000000 > > When us = 1000000, us / US should return "1 sec", no? > Sorry, I meant when the number of microseconds is smaller than a second. > Thank you. > --- > - Prasad ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] migration: Fix postcopy latency distribution formatting computation 2025-07-15 12:45 ` [PATCH 1/2] migration: Fix postcopy latency distribution formatting computation Fabiano Rosas 2025-07-15 14:01 ` Philippe Mathieu-Daudé 2025-07-16 10:26 ` Prasad Pandit @ 2025-07-17 13:31 ` Daniel P. Berrangé 2 siblings, 0 replies; 10+ messages in thread From: Daniel P. Berrangé @ 2025-07-17 13:31 UTC (permalink / raw) To: Fabiano Rosas Cc: qemu-devel, Peter Xu, Philippe Mathieu-Daudé, Peter Maydell On Tue, Jul 15, 2025 at 09:45:51AM -0300, Fabiano Rosas wrote: > Coverity has caught a bug in the formatting of time intervals for > postcopy latency distribution display in 'info migrate'. > > While bounds checking the labels array, sizeof is incorrectly being > used. ARRAY_SIZE is the correct form of obtaining the size of an > array. > > Fixes: 3345fb3b6d ("migration/postcopy: Add latency distribution report for blocktime") > Resolves: Coverity CID 1612248 > Suggested-by: Peter Maydell <peter.maydell@linaro.org> > Signed-off-by: Fabiano Rosas <farosas@suse.de> > --- > migration/migration-hmp-cmds.c | 6 ++---- > 1 file changed, 2 insertions(+), 4 deletions(-) > > diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c > index cef5608210..bb954881d7 100644 > --- a/migration/migration-hmp-cmds.c > +++ b/migration/migration-hmp-cmds.c > @@ -57,11 +57,9 @@ static const gchar *format_time_str(uint64_t us) > const char *units[] = {"us", "ms", "sec"}; > int index = 0; > > - while (us > 1000) { > + while (us > 1000 && index + 1 < ARRAY_SIZE(units)) { > us /= 1000; > - if (++index >= (sizeof(units) - 1)) { > - break; > - } > + index++; > } > > return g_strdup_printf("%"PRIu64" %s", us, units[index]); It occurrs to me that this is the same basic algorithmic problem as converting storage sizes from bytes to KB/MB/GB/etc. We have size_to_str() which does this conversion without needing any loop at all. Then there is freq_to_str() which has similar purpose but still uses a loop, instead of the shortcut size_to_str has. IMHO we should have a 'scaled_int_to_str' method that is common to any place we need such scaled integer string conversions, and then wrappers like "size_to_str", "freq_to_str" and "duration_to_str" that pass in the required list of unit strings, and the divisor and requested decimal precision, etc. With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :| ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/2] cutils: Add time_us_to_str 2025-07-15 12:45 [PATCH 0/2] migration: Fix possible access out of bounds Fabiano Rosas 2025-07-15 12:45 ` [PATCH 1/2] migration: Fix postcopy latency distribution formatting computation Fabiano Rosas @ 2025-07-15 12:45 ` Fabiano Rosas 2025-07-15 14:02 ` Philippe Mathieu-Daudé 1 sibling, 1 reply; 10+ messages in thread From: Fabiano Rosas @ 2025-07-15 12:45 UTC (permalink / raw) To: qemu-devel; +Cc: Peter Xu, Philippe Mathieu-Daudé, Peter Maydell The migration code has a function that converts a time value (us) to a string with the proper suffix. Move it to cutils since it's generic enough that it could be reused. Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Fabiano Rosas <farosas@suse.de> --- include/qemu/cutils.h | 1 + migration/migration-hmp-cmds.c | 17 ++--------------- util/cutils.c | 13 +++++++++++++ 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h index 36c68ce86c..7621726621 100644 --- a/include/qemu/cutils.h +++ b/include/qemu/cutils.h @@ -171,6 +171,7 @@ int qemu_strtosz_MiB(const char *nptr, const char **end, uint64_t *result); int qemu_strtosz_metric(const char *nptr, const char **end, uint64_t *result); char *size_to_str(uint64_t val); +char *time_us_to_str(uint64_t val); /** * freq_to_str: diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c index bb954881d7..1706f3a0f7 100644 --- a/migration/migration-hmp-cmds.c +++ b/migration/migration-hmp-cmds.c @@ -52,19 +52,6 @@ static void migration_global_dump(Monitor *mon) ms->clear_bitmap_shift); } -static const gchar *format_time_str(uint64_t us) -{ - const char *units[] = {"us", "ms", "sec"}; - int index = 0; - - while (us > 1000 && index + 1 < ARRAY_SIZE(units)) { - us /= 1000; - index++; - } - - return g_strdup_printf("%"PRIu64" %s", us, units[index]); -} - static void migration_dump_blocktime(Monitor *mon, MigrationInfo *info) { if (info->has_postcopy_blocktime) { @@ -121,8 +108,8 @@ static void migration_dump_blocktime(Monitor *mon, MigrationInfo *info) monitor_printf(mon, "Postcopy Latency Distribution:\n"); while (item) { - g_autofree const gchar *from = format_time_str(1UL << count); - g_autofree const gchar *to = format_time_str(1UL << (count + 1)); + g_autofree const gchar *from = time_us_to_str(1UL << count); + g_autofree const gchar *to = time_us_to_str(1UL << (count + 1)); monitor_printf(mon, " [ %8s - %8s ]: %10"PRIu64"\n", from, to, item->value); diff --git a/util/cutils.c b/util/cutils.c index 9803f11a59..023793211a 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -1004,6 +1004,19 @@ char *freq_to_str(uint64_t freq_hz) return g_strdup_printf("%0.3g %sHz", freq, si_prefix(exp10)); } +char *time_us_to_str(uint64_t us) +{ + const char *units[] = {"us", "ms", "sec"}; + int index = 0; + + while (us > 1000 && index + 1 < ARRAY_SIZE(units)) { + us /= 1000; + index++; + } + + return g_strdup_printf("%"PRIu64" %s", us, units[index]); +} + int qemu_pstrcmp0(const char **str1, const char **str2) { return g_strcmp0(*str1, *str2); -- 2.35.3 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] cutils: Add time_us_to_str 2025-07-15 12:45 ` [PATCH 2/2] cutils: Add time_us_to_str Fabiano Rosas @ 2025-07-15 14:02 ` Philippe Mathieu-Daudé 0 siblings, 0 replies; 10+ messages in thread From: Philippe Mathieu-Daudé @ 2025-07-15 14:02 UTC (permalink / raw) To: Fabiano Rosas, qemu-devel; +Cc: Peter Xu, Peter Maydell On 15/7/25 14:45, Fabiano Rosas wrote: > The migration code has a function that converts a time value (us) to a > string with the proper suffix. Move it to cutils since it's generic > enough that it could be reused. > > Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org> > Signed-off-by: Fabiano Rosas <farosas@suse.de> > --- > include/qemu/cutils.h | 1 + > migration/migration-hmp-cmds.c | 17 ++--------------- > util/cutils.c | 13 +++++++++++++ > 3 files changed, 16 insertions(+), 15 deletions(-) > > diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h > index 36c68ce86c..7621726621 100644 > --- a/include/qemu/cutils.h > +++ b/include/qemu/cutils.h > @@ -171,6 +171,7 @@ int qemu_strtosz_MiB(const char *nptr, const char **end, uint64_t *result); > int qemu_strtosz_metric(const char *nptr, const char **end, uint64_t *result); > > char *size_to_str(uint64_t val); > +char *time_us_to_str(uint64_t val); s/val/us/ > > /** > * freq_to_str: > diff --git a/migration/migration-hmp-cmds.c b/migration/migration-hmp-cmds.c > index bb954881d7..1706f3a0f7 100644 > --- a/migration/migration-hmp-cmds.c > +++ b/migration/migration-hmp-cmds.c > @@ -52,19 +52,6 @@ static void migration_global_dump(Monitor *mon) > ms->clear_bitmap_shift); > } > > -static const gchar *format_time_str(uint64_t us) > -{ > - const char *units[] = {"us", "ms", "sec"}; > - int index = 0; > - > - while (us > 1000 && index + 1 < ARRAY_SIZE(units)) { > - us /= 1000; > - index++; > - } > - > - return g_strdup_printf("%"PRIu64" %s", us, units[index]); > -} > - > static void migration_dump_blocktime(Monitor *mon, MigrationInfo *info) > { > if (info->has_postcopy_blocktime) { > @@ -121,8 +108,8 @@ static void migration_dump_blocktime(Monitor *mon, MigrationInfo *info) > monitor_printf(mon, "Postcopy Latency Distribution:\n"); > > while (item) { > - g_autofree const gchar *from = format_time_str(1UL << count); > - g_autofree const gchar *to = format_time_str(1UL << (count + 1)); > + g_autofree const gchar *from = time_us_to_str(1UL << count); > + g_autofree const gchar *to = time_us_to_str(1UL << (count + 1)); > > monitor_printf(mon, " [ %8s - %8s ]: %10"PRIu64"\n", > from, to, item->value); > diff --git a/util/cutils.c b/util/cutils.c > index 9803f11a59..023793211a 100644 > --- a/util/cutils.c > +++ b/util/cutils.c > @@ -1004,6 +1004,19 @@ char *freq_to_str(uint64_t freq_hz) > return g_strdup_printf("%0.3g %sHz", freq, si_prefix(exp10)); > } > > +char *time_us_to_str(uint64_t us) > +{ > + const char *units[] = {"us", "ms", "sec"}; (static) > + int index = 0; > + > + while (us > 1000 && index + 1 < ARRAY_SIZE(units)) { > + us /= 1000; > + index++; > + } > + > + return g_strdup_printf("%"PRIu64" %s", us, units[index]); > +} Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Thanks! ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-07-17 20:19 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-07-15 12:45 [PATCH 0/2] migration: Fix possible access out of bounds Fabiano Rosas 2025-07-15 12:45 ` [PATCH 1/2] migration: Fix postcopy latency distribution formatting computation Fabiano Rosas 2025-07-15 14:01 ` Philippe Mathieu-Daudé 2025-07-16 10:26 ` Prasad Pandit 2025-07-16 13:36 ` Fabiano Rosas 2025-07-17 6:28 ` Prasad Pandit 2025-07-17 12:35 ` Fabiano Rosas 2025-07-17 13:31 ` Daniel P. Berrangé 2025-07-15 12:45 ` [PATCH 2/2] cutils: Add time_us_to_str Fabiano Rosas 2025-07-15 14:02 ` Philippe Mathieu-Daudé
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).