Print this page
11972 resync smatch
@@ -26,10 +26,11 @@
#include "smatch_slist.h"
#include "smatch_extra.h"
static int my_whole_id;
static int my_member_id;
+static int skb_put_id;
STATE(cleared);
static void extra_mod_hook(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
{
@@ -122,23 +123,10 @@
if (!sym)
return FALSE;
return toplevel(sym->scope);
}
-static int was_initialized(struct expression *expr)
-{
- struct symbol *sym;
- char *name;
-
- name = expr_to_var_sym(expr, &sym);
- if (!name)
- return 0;
- if (sym->initializer)
- return 1;
- return 0;
-}
-
static void match_clear(const char *fn, struct expression *expr, void *_arg_no)
{
struct expression *ptr;
int arg_no = PTR_INT(_arg_no);
@@ -256,12 +244,25 @@
if (data->type != EXPR_SYMBOL)
return;
if (has_global_scope(data))
return;
- if (was_initialized(data))
+ if (was_memset(data))
return;
+ if (warn_on_holey_struct(data))
+ return;
+ check_members_initialized(data);
+}
+
+static void check_skb_put(struct expression *data)
+{
+ data = strip_expr(data);
+ if (!data)
+ return;
+ if (data->type == EXPR_PREOP && data->op == '&')
+ data = strip_expr(data->unop);
+
if (was_memset(data))
return;
if (warn_on_holey_struct(data))
return;
check_members_initialized(data);
@@ -289,20 +290,55 @@
return;
match_clear(NULL, expr, INT_PTR(param));
}
-static void match_assign(struct expression *expr)
+static struct smatch_state *alloc_expr_state(struct expression *expr)
{
+ struct smatch_state *state;
+ char *name;
+
+ name = expr_to_str(expr);
+ if (!name)
+ return NULL;
+
+ state = __alloc_smatch_state(0);
+ expr = strip_expr(expr);
+ state->name = alloc_sname(name);
+ free_string(name);
+ state->data = expr;
+ return state;
+}
+
+static void match_skb_put(const char *fn, struct expression *expr, void *unused)
+{
struct symbol *type;
+ struct smatch_state *state;
type = get_type(expr->left);
+ type = get_real_base_type(type);
if (!type || type->type != SYM_STRUCT)
return;
- set_state_expr(my_whole_id, expr->left, &cleared);
+ state = alloc_expr_state(expr->left);
+ set_state_expr(skb_put_id, expr->left, state);
}
+static void match_return_skb_put(struct expression *expr)
+{
+ struct sm_state *sm;
+ struct stree *stree;
+
+ if (is_error_return(expr))
+ return;
+
+ stree = __get_cur_stree();
+
+ FOR_EACH_MY_SM(skb_put_id, stree, sm) {
+ check_skb_put(sm->state->data);
+ } END_FOR_EACH_SM(sm);
+}
+
static void register_clears_argument(void)
{
struct token *token;
const char *func;
int arg;
@@ -367,11 +403,10 @@
add_function_hook("__memcpy", &match_clear, INT_PTR(0));
add_function_hook("__memzero", &match_clear, INT_PTR(0));
add_function_hook("__builtin_memset", &match_clear, INT_PTR(0));
add_function_hook("__builtin_memcpy", &match_clear, INT_PTR(0));
- add_hook(&match_assign, ASSIGNMENT_HOOK);
register_clears_argument();
select_return_states_hook(PARAM_CLEARED, &db_param_cleared);
register_copy_funcs_from_file();
}
@@ -384,5 +419,16 @@
my_member_id = id;
set_dynamic_states(my_member_id);
add_extra_mod_hook(&extra_mod_hook);
}
+void check_rosenberg3(int id)
+{
+ if (option_project != PROJ_KERNEL)
+ return;
+
+ skb_put_id = id;
+ set_dynamic_states(skb_put_id);
+ add_function_assign_hook("skb_put", &match_skb_put, NULL);
+ add_hook(&match_return_skb_put, RETURN_HOOK);
+}
+