forked from Mirror/frr
Merge pull request #17943 from opensourcerouting/clear-event-cpu-uaf
lib: fix use after free in `clear event cpu`
This commit is contained in:
commit
f9e11d6974
22
lib/event.c
22
lib/event.c
|
@ -111,6 +111,11 @@ static struct cpu_event_history *cpu_records_get(struct event_loop *loop,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cpu_records_clear(struct cpu_event_history *p)
|
||||||
|
{
|
||||||
|
memset(p->_clear_begin, 0, p->_clear_end - p->_clear_begin);
|
||||||
|
}
|
||||||
|
|
||||||
static void cpu_records_free(struct cpu_event_history **p)
|
static void cpu_records_free(struct cpu_event_history **p)
|
||||||
{
|
{
|
||||||
XFREE(MTYPE_EVENT_STATS, *p);
|
XFREE(MTYPE_EVENT_STATS, *p);
|
||||||
|
@ -250,20 +255,15 @@ static void cpu_record_clear(uint8_t filter)
|
||||||
for (ALL_LIST_ELEMENTS_RO(masters, ln, m)) {
|
for (ALL_LIST_ELEMENTS_RO(masters, ln, m)) {
|
||||||
frr_with_mutex (&m->mtx) {
|
frr_with_mutex (&m->mtx) {
|
||||||
struct cpu_event_history *item;
|
struct cpu_event_history *item;
|
||||||
struct cpu_records_head old[1];
|
|
||||||
|
|
||||||
cpu_records_init(old);
|
/* it isn't possible to free the memory here
|
||||||
cpu_records_swap_all(old, m->cpu_records);
|
* because some of these will be in use (e.g.
|
||||||
|
* the one we're currently running in!)
|
||||||
while ((item = cpu_records_pop(old))) {
|
*/
|
||||||
|
frr_each (cpu_records, m->cpu_records, item) {
|
||||||
if (item->types & filter)
|
if (item->types & filter)
|
||||||
cpu_records_free(&item);
|
cpu_records_clear(item);
|
||||||
else
|
|
||||||
cpu_records_add(m->cpu_records,
|
|
||||||
item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu_records_fini(old);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,6 +139,10 @@ struct cpu_event_history {
|
||||||
struct cpu_records_item item;
|
struct cpu_records_item item;
|
||||||
|
|
||||||
void (*func)(struct event *e);
|
void (*func)(struct event *e);
|
||||||
|
|
||||||
|
/* fields between the pair of these two are nulled on "clear event cpu" */
|
||||||
|
char _clear_begin[0];
|
||||||
|
|
||||||
atomic_size_t total_cpu_warn;
|
atomic_size_t total_cpu_warn;
|
||||||
atomic_size_t total_wall_warn;
|
atomic_size_t total_wall_warn;
|
||||||
atomic_size_t total_starv_warn;
|
atomic_size_t total_starv_warn;
|
||||||
|
@ -149,6 +153,10 @@ struct cpu_event_history {
|
||||||
} real;
|
} real;
|
||||||
struct time_stats cpu;
|
struct time_stats cpu;
|
||||||
atomic_uint_fast32_t types;
|
atomic_uint_fast32_t types;
|
||||||
|
|
||||||
|
/* end of cleared region */
|
||||||
|
char _clear_end[0];
|
||||||
|
|
||||||
const char *funcname;
|
const char *funcname;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue