mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-21 23:01:03 +00:00
Fix undefined behaviour in RVector, RPVector, RInterval and container_of ##fix
* All those basic primites were based on wrong assumptions * Added more return_if preconditions on several anal functions
This commit is contained in:
parent
69815e22e4
commit
ad2df6a14c
@ -1436,10 +1436,12 @@ beach:
|
||||
}
|
||||
|
||||
R_API int r_anal_function_bb(RAnal *anal, RAnalFunction *fcn, ut64 addr, int depth) {
|
||||
r_return_val_if_fail (anal && fcn, -1);
|
||||
return fcn_recurse (anal, fcn, addr, anal->opt.bb_max_size, depth - 1);
|
||||
}
|
||||
|
||||
R_API bool r_anal_check_fcn(RAnal *anal, ut8 *buf, ut16 bufsz, ut64 addr, ut64 low, ut64 high) {
|
||||
r_return_val_if_fail (anal && buf, false);
|
||||
RAnalOp op = {
|
||||
0
|
||||
};
|
||||
@ -1480,6 +1482,7 @@ R_API bool r_anal_check_fcn(RAnal *anal, ut8 *buf, ut16 bufsz, ut64 addr, ut64 l
|
||||
}
|
||||
|
||||
R_API void r_anal_trim_jmprefs(RAnal *anal, RAnalFunction *fcn) {
|
||||
r_return_if_fail (anal && fcn);
|
||||
RAnalRef *ref;
|
||||
RList *refs = r_anal_function_get_refs (fcn);
|
||||
RListIter *iter;
|
||||
@ -1495,6 +1498,7 @@ R_API void r_anal_trim_jmprefs(RAnal *anal, RAnalFunction *fcn) {
|
||||
}
|
||||
|
||||
R_API void r_anal_del_jmprefs(RAnal *anal, RAnalFunction *fcn) {
|
||||
r_return_if_fail (anal && fcn);
|
||||
RAnalRef *ref;
|
||||
RList *refs = r_anal_function_get_refs (fcn);
|
||||
RListIter *iter;
|
||||
@ -1509,21 +1513,24 @@ R_API void r_anal_del_jmprefs(RAnal *anal, RAnalFunction *fcn) {
|
||||
|
||||
/* Does NOT invalidate read-ahead cache. */
|
||||
R_API int r_anal_function(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 len, int reftype) {
|
||||
RPVector *metas = r_meta_get_all_in(anal, addr, R_META_TYPE_ANY);
|
||||
void **it;
|
||||
r_pvector_foreach (metas, it) {
|
||||
RAnalMetaItem *meta = ((RIntervalNode *)*it)->data;
|
||||
switch (meta->type) {
|
||||
case R_META_TYPE_DATA:
|
||||
case R_META_TYPE_STRING:
|
||||
case R_META_TYPE_FORMAT:
|
||||
r_pvector_free (metas);
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
r_return_val_if_fail (anal && fcn, 0);
|
||||
RPVector *metas = r_meta_get_all_in (anal, addr, R_META_TYPE_ANY);
|
||||
if (metas) {
|
||||
void **it;
|
||||
r_pvector_foreach (metas, it) {
|
||||
RAnalMetaItem *meta = ((RIntervalNode *)*it)->data;
|
||||
switch (meta->type) {
|
||||
case R_META_TYPE_DATA:
|
||||
case R_META_TYPE_STRING:
|
||||
case R_META_TYPE_FORMAT:
|
||||
r_pvector_free (metas);
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
r_pvector_free (metas);
|
||||
}
|
||||
r_pvector_free (metas);
|
||||
if (anal->opt.norevisit) {
|
||||
if (!anal->visited) {
|
||||
anal->visited = set_u_new ();
|
||||
|
@ -257,14 +257,18 @@ R_API void r_anal_function_delete_vars_by_kind(RAnalFunction *fcn, RAnalVarKind
|
||||
}
|
||||
|
||||
R_API void r_anal_function_delete_all_vars(RAnalFunction *fcn) {
|
||||
void **it;
|
||||
r_pvector_foreach (&fcn->vars, it) {
|
||||
var_free (*it);
|
||||
r_return_if_fail (fcn);
|
||||
if (fcn->vars.v.len > 0) {
|
||||
void **it;
|
||||
r_pvector_foreach (&fcn->vars, it) {
|
||||
var_free (*it);
|
||||
}
|
||||
}
|
||||
r_pvector_clear (&fcn->vars);
|
||||
}
|
||||
|
||||
R_API void r_anal_function_delete_unused_vars(RAnalFunction *fcn) {
|
||||
r_return_if_fail (fcn);
|
||||
void **v;
|
||||
RPVector *vars_clone = (RPVector *)r_vector_clone ((RVector *)&fcn->vars);
|
||||
r_pvector_foreach (vars_clone, v) {
|
||||
@ -283,6 +287,7 @@ R_API void r_anal_function_delete_var(RAnalFunction *fcn, RAnalVar *var) {
|
||||
}
|
||||
|
||||
R_API RList *r_anal_var_deserialize(const char *ser) {
|
||||
r_return_val_if_fail (ser, NULL);
|
||||
RList *ret = r_list_newf ((RListFree)r_anal_var_proto_free);
|
||||
while (*ser) {
|
||||
RAnalVarProt *v = R_NEW0 (RAnalVarProt);
|
||||
@ -381,6 +386,7 @@ static inline void sanitize_var_serial(char *name, bool colon) {
|
||||
}
|
||||
|
||||
static inline bool serialize_single_var(RAnalVarProt *vp, RStrBuf *sb) {
|
||||
r_return_val_if_fail (vp && sb, false);
|
||||
// shouldn't have special chars in them anyways, so replace in place
|
||||
sanitize_var_serial (vp->name, false);
|
||||
sanitize_var_serial (vp->type, true);
|
||||
@ -1364,11 +1370,13 @@ static RList *var_generate_list(RAnal *a, RAnalFunction *fcn, int kind) {
|
||||
if (kind < 1) {
|
||||
kind = R_ANAL_VAR_KIND_BPV; // by default show vars
|
||||
}
|
||||
void **it;
|
||||
r_pvector_foreach (&fcn->vars, it) {
|
||||
RAnalVar *var = *it;
|
||||
if (var->kind == kind) {
|
||||
r_list_push (list, var);
|
||||
if (fcn->vars.v.len > 0) {
|
||||
void **it;
|
||||
r_pvector_foreach (&fcn->vars, it) {
|
||||
RAnalVar *var = *it;
|
||||
if (var->kind == kind) {
|
||||
r_list_push (list, var);
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
|
@ -722,11 +722,7 @@ static inline void r_run_call10(void *fcn, void *arg1, void *arg2, void *arg3, v
|
||||
}
|
||||
|
||||
#ifndef container_of
|
||||
# ifdef _MSC_VER
|
||||
# define container_of(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member)))
|
||||
# else
|
||||
# define container_of(ptr, type, member) ((type *)((char *)(__typeof__(((type *)0)->member) *){ptr} - offsetof(type, member)))
|
||||
# endif
|
||||
#define container_of(ptr, type, member) (ptr? ((type *)((char *)(ptr) - r_offsetof(type, member))): NULL)
|
||||
#endif
|
||||
|
||||
// reference counter
|
||||
|
@ -294,10 +294,12 @@ static inline void **r_pvector_flush(RPVector *vec) {
|
||||
* }
|
||||
*/
|
||||
#define r_pvector_foreach(vec, it) \
|
||||
if ((vec)->v.len > 0) \
|
||||
for (it = (void **)(vec)->v.a; it != (void **)(vec)->v.a + (vec)->v.len; it++)
|
||||
|
||||
// like r_pvector_foreach() but inverse
|
||||
#define r_pvector_foreach_prev(vec, it) \
|
||||
if ((vec)->v.len > 0) \
|
||||
for (it = ((vec)->v.len == 0 ? NULL : (void **)(vec)->v.a + (vec)->v.len - 1); it != NULL && it != (void **)(vec)->v.a - 1; it--)
|
||||
|
||||
/*
|
||||
|
@ -168,6 +168,7 @@ R_API bool r_interval_tree_resize(RIntervalTree *tree, RIntervalNode *node, ut64
|
||||
// This must always return the topmost node that matches start!
|
||||
// Otherwise r_interval_tree_first_at will break!!!
|
||||
R_API RIntervalNode *r_interval_tree_node_at(RIntervalTree *tree, ut64 start) {
|
||||
r_return_val_if_fail (tree, NULL);
|
||||
RIntervalNode *node = tree->root;
|
||||
while (node) {
|
||||
if (start < node->start) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user