From b17d60110d7138567b919b18b7925d2a7d4648f2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 5 May 2014 23:30:44 +0300 Subject: [PATCH] clear_buffer: remove this code The smatch_clear_buffer.c was supposed to help with check_rosenberg.c and also for checking if we used uninitialized variables. But it sort of duplicates smatch_param_cleared.c and smatch_struct_assignment.c. Also the uninitialized variable code never worked to the point where I could commit it. This code was just messing me up. Delete it for now. Move the remaining useful bit to smatch_struct_assignment.c. Signed-off-by: Dan Carpenter --- Makefile | 2 +- check_list.h | 1 - smatch.h | 4 - smatch_clear_buffer.c | 248 --------------------------------------------- smatch_struct_assignment.c | 21 ++++ 5 files changed, 22 insertions(+), 254 deletions(-) delete mode 100644 smatch_clear_buffer.c diff --git a/Makefile b/Makefile index e7eae2f5..e9da7af0 100644 --- a/Makefile +++ b/Makefile @@ -60,7 +60,7 @@ SMATCH_FILES=smatch_flow.o smatch_conditions.o smatch_slist.o smatch_states.o \ smatch_param_limit.o smatch_param_filter.o \ smatch_param_set.o smatch_comparison.o smatch_local_values.o \ smatch_function_ptrs.o smatch_annotate.o smatch_string_list.o \ - smatch_param_cleared.o smatch_clear_buffer.o smatch_start_states.o \ + smatch_param_cleared.o smatch_start_states.o \ smatch_recurse.o smatch_data_source.o smatch_type_val.o \ smatch_common_functions.o smatch_struct_assignment.o \ smatch_unknown_value.o smatch_stored_conditions.o avl.o diff --git a/check_list.h b/check_list.h index 960567a2..537ae282 100644 --- a/check_list.h +++ b/check_list.h @@ -18,7 +18,6 @@ CK(register_param_limit) CK(register_param_filter) CK(register_param_set) CK(register_param_cleared) -CK(register_clear_buffer) CK(register_struct_assignment) CK(register_comparison) CK(register_comparison_links) diff --git a/smatch.h b/smatch.h index 69ee3800..09a17729 100644 --- a/smatch.h +++ b/smatch.h @@ -728,10 +728,6 @@ void insert_string(struct string_list **str_list, char *str); struct string_list *clone_str_list(struct string_list *orig); struct string_list *combine_string_lists(struct string_list *one, struct string_list *two); -/* smatch_clear_buffer.c */ -int is_uninitialized(struct expression *expr); -int has_uninitialized_members(struct expression *expr); - /* smatch_start_states.c */ struct stree *get_start_states(void); diff --git a/smatch_clear_buffer.c b/smatch_clear_buffer.c deleted file mode 100644 index 6439497f..00000000 --- a/smatch_clear_buffer.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) 2013 Oracle. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt - */ - -#include "smatch.h" -#include "smatch_slist.h" -#include "smatch_extra.h" - -static int my_id; - -STATE(uninitialized); -STATE(initialized); - -static int type_sym_array(struct expression *expr) -{ - struct symbol *type; - - /* remove casting the array to a pointer */ - expr = strip_expr(expr); - type = get_type(expr); - if (type && type->type == SYM_ARRAY) - return 1; - return 0; -} - -static void set_members_uninitialized(struct expression *expr) -{ - struct symbol *type, *sym, *tmp; - char *name; - char buf[256]; - - type = get_type(expr); - if (!type) - return; - - if (type->type != SYM_PTR) - return; - type = get_real_base_type(type); - - name = expr_to_var_sym(expr, &sym); - if (!name || !sym) - goto free; - - FOR_EACH_PTR(type->symbol_list, tmp) { - if (!tmp->ident) - continue; - snprintf(buf, sizeof(buf), "%s->%s", name, tmp->ident->name); - set_state(my_id, buf, sym, &uninitialized); - } END_FOR_EACH_PTR(tmp); - -free: - free_string(name); -} - -static void initialize_struct_members(struct symbol *type, struct expression *expr, struct expression *to) -{ - struct symbol *tmp; - struct expression *member; - struct expression *assign; - int op = '*'; - - if (expr->type == EXPR_PREOP && expr->op == '&') { - expr = strip_expr(expr->unop); - op = '.'; - } - - FOR_EACH_PTR(type->symbol_list, tmp) { - if (!tmp->ident) - continue; - member = member_expression(expr, op, tmp->ident); - if (type_sym_array(member)) - continue; - - /* - * FIXME: the problem here is that sometimes we have: - * memset(&my_struct, 0xff, sizeof(my_struct)); - * and my_struct->foo is a 1 bit bitfield. There is a check - * which complains that "255 doesn't fit in ->foo". - * - * For now I just have this ugly hack. But really it's not - * handling the memset(..., 0xff, ...) correctly at all so one - * more hack barely makes a difference. - * - */ - if (to && type_positive_bits(get_type(member)) >= type_positive_bits(get_type(to))) - assign = assign_expression(member, to); - else - assign = assign_expression(member, member); - - __pass_to_client(assign, ASSIGNMENT_HOOK); - } END_FOR_EACH_PTR(tmp); -} - -static void initialize_base_type(struct symbol *type, struct expression *expr, - struct expression *to) -{ - struct expression *assign; - - if (type == &void_ctype) - return; - if (expr->type == EXPR_PREOP && expr->op == '&') - expr = strip_expr(expr->unop); - else - expr = deref_expression(expr); - if (!to) - to = expr; - /* FIXME: see the FIXME in initialize_struct_members() */ - if (type_positive_bits(get_type(expr)) < type_positive_bits(get_type(to))) - to = expr; - assign = assign_expression(expr, to); - __pass_to_client(assign, ASSIGNMENT_HOOK); -} - -static void set_initialized(struct expression *expr, struct expression *to) -{ - struct symbol *type; - - expr = strip_expr(expr); - - type = get_type(expr); - if (!type || type->type != SYM_PTR) - return; - type = get_real_base_type(type); - if (!type) - return; - if (type->type == SYM_BASETYPE) - initialize_base_type(type, expr, to); - if (type->type == SYM_STRUCT) { - if (expr->type != EXPR_PREOP || expr->op != '&') - expr = deref_expression(expr); - initialize_struct_members(type, expr, to); - } -} - -int is_uninitialized(struct expression *expr) -{ - struct sm_state *sm; - - sm = get_sm_state_expr(my_id, expr); - if (!sm) - return 0; - return slist_has_state(sm->possible, &uninitialized); -} - -int has_uninitialized_members(struct expression *expr) -{ - struct symbol *sym; - struct symbol *tmp; - char *name; - char buf[256]; - struct sm_state *sm; - - sym = get_type(expr); - if (!sym) - return 0; - - if (sym->type == SYM_PTR) - sym = get_real_base_type(sym); - - name = expr_to_var(expr); - if (!name) - return 0; - - FOR_EACH_PTR(sym->symbol_list, tmp) { - if (!tmp->ident) - continue; - snprintf(buf, sizeof(buf), "%s->%s", name, tmp->ident->name); - sm = get_sm_state(my_id, buf, sym); - if (!sm) - continue; - if (slist_has_state(sm->possible, &uninitialized)) - return 1; - } END_FOR_EACH_PTR(tmp); - - free_string(name); - return 0; -} - -static void match_alloc(const char *fn, struct expression *expr, void *_size_arg) -{ - set_members_uninitialized(expr->left); -} - -static void db_param_cleared(struct expression *expr, int param, char *key, char *value) -{ - struct expression *arg; - - while (expr->type == EXPR_ASSIGNMENT) - expr = strip_expr(expr->right); - if (expr->type != EXPR_CALL) - return; - - arg = get_argument_from_call_expr(expr->args, param); - if (!arg) - return; - - if (strcmp(value, "0") == 0) - set_initialized(arg, zero_expr()); - else - set_initialized(arg, NULL); -} - -static void reset_initialized(struct sm_state *sm, struct expression *mod_expr) -{ - set_state(my_id, sm->name, sm->sym, &initialized); -} - -#define USB_DIR_IN 0x80 -static void match_usb_control_msg(const char *fn, struct expression *expr, void *_size_arg) -{ - struct expression *inout; - struct expression *buf; - sval_t sval; - - inout = get_argument_from_call_expr(expr->args, 3); - buf = get_argument_from_call_expr(expr->args, 6); - - if (get_value(inout, &sval) && !(sval.uvalue & USB_DIR_IN)) - return; - - set_initialized(buf, NULL); -} - -void register_clear_buffer(int id) -{ - my_id = id; - if (option_project == PROJ_KERNEL) { - add_function_assign_hook("kmalloc", &match_alloc, NULL); - add_function_hook("usb_control_msg", &match_usb_control_msg, NULL); - } - add_modification_hook(my_id, &reset_initialized); - - select_return_states_hook(PARAM_CLEARED, &db_param_cleared); -} - diff --git a/smatch_struct_assignment.c b/smatch_struct_assignment.c index b23158aa..bfa02615 100644 --- a/smatch_struct_assignment.c +++ b/smatch_struct_assignment.c @@ -228,6 +228,26 @@ static void register_clears_param(void) clear_token_alloc(); } +static void db_param_cleared(struct expression *expr, int param, char *key, char *value) +{ + struct expression *arg; + + while (expr->type == EXPR_ASSIGNMENT) + expr = strip_expr(expr->right); + if (expr->type != EXPR_CALL) + return; + + arg = get_argument_from_call_expr(expr->args, param); + if (!arg) + return; + + if (strcmp(value, "0") == 0) + __struct_members_copy(COPY_MEMSET, remove_addr(arg), zero_expr()); + else + __struct_members_copy(COPY_MEMCPY, remove_addr(arg), NULL); + +} + void register_struct_assignment(int id) { add_function_hook("memset", &match_memset, NULL); @@ -236,4 +256,5 @@ void register_struct_assignment(int id) add_function_hook("memmove", &match_memcpy, INT_PTR(0)); register_clears_param(); + select_return_states_hook(PARAM_CLEARED, &db_param_cleared); } -- 2.11.4.GIT