Coverity reports a data race where coverage_read() accesses idx_count
without holding the coverage_mutex, while coverage_run() writes to
idx_count with the mutex held (as is done 1 out of 1 times when
writing).
The race occurs when coverage_read() reads idx_count to calculate the
array index into c[i]->min[] without synchronization. If coverage_run()
concurrently updates idx_count, coverage_read() could:
1. Read a stale value of idx_count with no memory barrier guaranteeing
visibility of the update
2. Access the wrong index in the min[] array, reporting statistics from
the wrong time slot
Fix by capturing idx_count once while holding the mutex, then using
that consistent snapshot value when accessing the arrays.
Fixes: 98cf638b19c2 ("coverage: Reimplement the "ovs-appctl coverage/show"
command.")
Acked-by: Mike Pattrick <[email protected]>
Signed-off-by: Eelco Chaudron <[email protected]>
---
lib/coverage.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/coverage.c b/lib/coverage.c
index a95b6aa25..24792fb77 100644
--- a/lib/coverage.c
+++ b/lib/coverage.c
@@ -223,6 +223,7 @@ coverage_read(struct svec *lines)
{
struct coverage_counter **c = coverage_counters;
unsigned long long int *totals;
+ unsigned int last_idx;
size_t n_never_hit;
uint32_t hash;
size_t i;
@@ -238,6 +239,7 @@ coverage_read(struct svec *lines)
totals = xmalloc(n_coverage_counters * sizeof *totals);
ovs_mutex_lock(&coverage_mutex);
+ last_idx = (idx_count - 1) % MIN_AVG_LEN;
for (i = 0; i < n_coverage_counters; i++) {
totals[i] = c[i]->total;
}
@@ -252,8 +254,7 @@ coverage_read(struct svec *lines)
xasprintf("%-24s %5.1f/sec %9.3f/sec "
"%13.4f/sec total: %llu",
c[i]->name,
- (c[i]->min[(idx_count - 1) % MIN_AVG_LEN]
- * 1000.0 / COVERAGE_RUN_INTERVAL),
+ c[i]->min[last_idx] * 1000.0 / COVERAGE_RUN_INTERVAL,
coverage_array_sum(c[i]->min, MIN_AVG_LEN) / 60.0,
coverage_array_sum(c[i]->hr, HR_AVG_LEN) / 3600.0,
totals[i]));
--
2.52.0
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev