fix a mem-leak (#1147)

* fix a mem-leak.

* check the uc and l1_map before using them.

* fix multi-level free bug.

* Add pointer check.
This commit is contained in:
Chen Huitao
2019-10-05 15:11:46 +08:00
committed by Nguyen Anh Quynh
parent 355eaecc12
commit 79d89e5d3b

View File

@ -135,24 +135,57 @@ static void cpu_gen_init(struct uc_struct *uc)
tcg_context_init(uc->tcg_ctx); tcg_context_init(uc->tcg_ctx);
} }
static void tb_clean_internal(struct uc_struct *uc, int i, void** lp) static void tb_clean_internal(void **p, int x)
{ {
if (i == 0 || lp == 0) { int i;
return; void **q;
}
tb_clean_internal(uc, i-1, (void*)(((char*)*lp) + ((0 >> (i * V_L2_BITS)) & (V_L2_SIZE - 1)))); if (x <= 1) {
if (lp && *lp) { for (i = 0; i < V_L2_SIZE; i++) {
g_free(*lp); q = p[i];
if (q) {
g_free(q);
}
}
g_free(p);
} else {
for (i = 0; i < V_L2_SIZE; i++) {
q = p[i];
if (q) {
tb_clean_internal(q, x - 1);
}
}
g_free(p);
} }
} }
void tb_cleanup(struct uc_struct *uc) void tb_cleanup(struct uc_struct *uc)
{ {
int index = 0; int i, x;
/* Level 1. Always allocated. */ void **p;
void** lp = uc->l1_map + ((index >> V_L1_SHIFT) & (V_L1_SIZE - 1));
/* Level 2..N-1. */ if (uc) {
tb_clean_internal(uc, V_L1_SHIFT / V_L2_BITS, lp); if (uc->l1_map) {
x = V_L1_SHIFT / V_L2_BITS;
if (x <= 1) {
for (i = 0; i < V_L1_SIZE; i++) {
p = uc->l1_map[i];
if (p) {
g_free(p);
uc->l1_map[i] = NULL;
}
}
} else {
for (i = 0; i < V_L1_SIZE; i++) {
p = uc->l1_map[i];
if (p) {
tb_clean_internal(p, x - 1);
uc->l1_map[i] = NULL;
}
}
}
}
}
} }
/* return non zero if the very first instruction is invalid so that /* return non zero if the very first instruction is invalid so that