2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-09 13:49:05 +00:00

dpif-netdev: Prevent unsafe access when retrieving meter stats.

dpif_netdev_meter_get() retrieved a pointer to a meter entry without
holding a lock.  It's possible that another thread could have deleted
that entry between retrieving the pointer and dereferencing the pointer.
This makes the function hold the lock the entire time the meter entry is
needed.

Found by inspection.

Signed-off-by: Justin Pettit <jpettit@ovn.org>
Acked-by: Flavio Leitner <fbl@sysclose.org>
This commit is contained in:
Justin Pettit
2018-08-28 17:38:25 -07:00
parent d0db81eac8
commit 866bc7567a

View File

@@ -5243,20 +5243,22 @@ dpif_netdev_meter_get(const struct dpif *dpif,
struct ofputil_meter_stats *stats, uint16_t n_bands)
{
const struct dp_netdev *dp = get_dp_netdev(dpif);
const struct dp_meter *meter;
uint32_t meter_id = meter_id_.uint32;
int retval = 0;
if (meter_id >= MAX_METERS) {
return EFBIG;
}
meter = dp->meters[meter_id];
meter_lock(dp, meter_id);
const struct dp_meter *meter = dp->meters[meter_id];
if (!meter) {
return ENOENT;
retval = ENOENT;
goto done;
}
if (stats) {
int i = 0;
meter_lock(dp, meter_id);
stats->packet_in_count = meter->packet_count;
stats->byte_in_count = meter->byte_count;
@@ -5264,11 +5266,13 @@ dpif_netdev_meter_get(const struct dpif *dpif,
stats->bands[i].packet_count = meter->bands[i].packet_count;
stats->bands[i].byte_count = meter->bands[i].byte_count;
}
meter_unlock(dp, meter_id);
stats->n_bands = i;
}
return 0;
done:
meter_unlock(dp, meter_id);
return retval;
}
static int