Skip to content

Commit

Permalink
dpif-netdev: Prevent unsafe access when retrieving meter stats.
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Flavio Leitner <[email protected]>
  • Loading branch information
justinpettit committed Sep 4, 2018
1 parent d0db81e commit 866bc75
Showing 1 changed file with 10 additions and 6 deletions.
16 changes: 10 additions & 6 deletions lib/dpif-netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -5243,32 +5243,36 @@ 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;

for (i = 0; i < n_bands && i < meter->n_bands; ++i) {
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
Expand Down

0 comments on commit 866bc75

Please sign in to comment.