Print this page
12724 update smatch to 0.6.1-rc1-il-5


  51 static int my_id;
  52 
  53 mtag_t str_to_mtag(const char *str)
  54 {
  55         unsigned char c[MD5_DIGEST_LENGTH];
  56         unsigned long long *tag = (unsigned long long *)&c;
  57         MD5_CTX mdContext;
  58         int len;
  59 
  60         len = strlen(str);
  61         MD5_Init(&mdContext);
  62         MD5_Update(&mdContext, str, len);
  63         MD5_Final(c, &mdContext);
  64 
  65         *tag &= ~MTAG_ALIAS_BIT;
  66         *tag &= ~MTAG_OFFSET_MASK;
  67 
  68         return *tag;
  69 }
  70 
  71 const struct {
  72         const char *name;
  73         int size_arg;
  74 } allocator_info[] = {
  75         { "kmalloc", 0 },
  76         { "kzalloc", 0 },
  77         { "devm_kmalloc", 1},
  78         { "devm_kzalloc", 1},
  79 };
  80 
  81 static bool is_mtag_call(struct expression *expr)












  82 {
  83         struct expression *arg;
  84         int i;









  85         sval_t sval;
  86 






  87         if (expr->type != EXPR_CALL ||
  88             expr->fn->type != EXPR_SYMBOL ||
  89             !expr->fn->symbol)
  90                 return false;


  91 
  92         for (i = 0; i < ARRAY_SIZE(allocator_info); i++) {
  93                 if (strcmp(expr->fn->symbol->ident->name, allocator_info[i].name) == 0)
  94                         break;
  95         }
  96         if (i == ARRAY_SIZE(allocator_info))
  97                 return false;
  98 
  99         arg = get_argument_from_call_expr(expr->args, allocator_info[i].size_arg);
 100         if (!get_implied_value(arg, &sval))
 101                 return false;
 102 
 103         return true;


 104 }
 105 
 106 struct smatch_state *swap_mtag_return(struct expression *expr, struct smatch_state *state)
 107 {
 108         struct expression *left, *right;
 109         char *left_name, *right_name;
 110         struct symbol *left_sym;
 111         struct range_list *rl;
 112         char buf[256];
 113         mtag_t tag;
 114         sval_t tag_sval;
 115 
 116         if (!expr || expr->type != EXPR_ASSIGNMENT || expr->op != '=')
 117                 return state;




 118 
 119         if (!estate_rl(state) || strcmp(state->name, "0,4096-ptr_max") != 0)
 120                 return state;
 121 
 122         left = strip_expr(expr->left);
 123         right = strip_expr(expr->right);
 124 
 125         if (!is_mtag_call(right))
 126                 return state;
 127 
 128         left_name = expr_to_str_sym(left, &left_sym);
 129         if (!left_name || !left_sym)
 130                 return state;
 131         right_name = expr_to_str(right);
 132 
 133         snprintf(buf, sizeof(buf), "%s %s %s %s", get_filename(), get_function(),
 134                  left_name, right_name);
 135         tag = str_to_mtag(buf);
 136         tag_sval.type = estate_type(state);
 137         tag_sval.uvalue = tag;
 138 
 139         rl = rl_filter(estate_rl(state), valid_ptr_rl);
 140         rl = clone_rl(rl);
 141         add_range(&rl, tag_sval, tag_sval);
 142 
 143         sql_insert_mtag_about(tag, left_name, buf);
 144 
 145         free_string(left_name);
 146         free_string(right_name);
 147 
 148         return alloc_estate_rl(rl);
 149 }
 150 
 151 int get_string_mtag(struct expression *expr, mtag_t *tag)
 152 {
 153         mtag_t xor;
 154 
 155         if (expr->type != EXPR_STRING || !expr->string)
 156                 return 0;
 157 
 158         /* I was worried about collisions so I added a xor */
 159         xor = str_to_mtag("__smatch string");
 160         *tag = str_to_mtag(expr->string->data);
 161         *tag = *tag ^ xor;
 162 
 163         return 1;




  51 static int my_id;
  52 
  53 mtag_t str_to_mtag(const char *str)
  54 {
  55         unsigned char c[MD5_DIGEST_LENGTH];
  56         unsigned long long *tag = (unsigned long long *)&c;
  57         MD5_CTX mdContext;
  58         int len;
  59 
  60         len = strlen(str);
  61         MD5_Init(&mdContext);
  62         MD5_Update(&mdContext, str, len);
  63         MD5_Final(c, &mdContext);
  64 
  65         *tag &= ~MTAG_ALIAS_BIT;
  66         *tag &= ~MTAG_OFFSET_MASK;
  67 
  68         return *tag;
  69 }
  70 
  71 static int save_allocator(void *_allocator, int argc, char **argv, char **azColName)
  72 {
  73         char **allocator = _allocator;






  74 
  75         if (*allocator) {
  76                 if (strcmp(*allocator, argv[0]) == 0)
  77                         return 0;
  78                 /* should be impossible */
  79                 free_string(*allocator);
  80                 *allocator = alloc_string("unknown");
  81                 return 0;
  82         }
  83         *allocator = alloc_string(argv[0]);
  84         return 0;
  85 }
  86 
  87 char *get_allocator_info_from_tag(mtag_t tag)
  88 {
  89         char *allocator = NULL;
  90 
  91         run_sql(save_allocator, &allocator,
  92                 "select value from mtag_info where tag = %lld and type = %d;",
  93                 tag, ALLOCATOR);
  94 
  95         return allocator;
  96 }
  97 
  98 static char *get_allocator_info(struct expression *expr, struct smatch_state *state)
  99 {
 100         sval_t sval;
 101 
 102         if (expr->type != EXPR_ASSIGNMENT)
 103                 return NULL;
 104         if (estate_get_single_value(state, &sval))
 105                 return get_allocator_info_from_tag(sval.value);
 106 
 107         expr = strip_expr(expr->right);
 108         if (expr->type != EXPR_CALL ||
 109             !expr->fn ||
 110             expr->fn->type != EXPR_SYMBOL)
 111                 return NULL;
 112         return expr_to_str(expr->fn);
 113 }
 114 
 115 static void update_mtag_info(struct expression *expr, mtag_t tag,
 116                              const char *left_name, const char *tag_info,
 117                              struct smatch_state *state)
 118 {
 119         char *allocator;

 120 
 121         sql_insert_mtag_about(tag, left_name, tag_info);


 122 
 123         allocator = get_allocator_info(expr, state);
 124         if (allocator)
 125                 sql_insert_mtag_info(tag, ALLOCATOR, allocator);
 126 }
 127 
 128 struct smatch_state *get_mtag_return(struct expression *expr, struct smatch_state *state)
 129 {
 130         struct expression *left, *right;
 131         char *left_name, *right_name;
 132         struct symbol *left_sym;
 133         struct range_list *rl;
 134         char buf[256];
 135         mtag_t tag;
 136         sval_t tag_sval;
 137 
 138         if (!expr || expr->type != EXPR_ASSIGNMENT || expr->op != '=')
 139                 return NULL;
 140         if (!is_fresh_alloc(expr->right))
 141                 return NULL;
 142         if (!rl_intersection(estate_rl(state), valid_ptr_rl))
 143                 return NULL;
 144 



 145         left = strip_expr(expr->left);
 146         right = strip_expr(expr->right);
 147 



 148         left_name = expr_to_str_sym(left, &left_sym);
 149         if (!left_name || !left_sym)
 150                 return NULL;
 151         right_name = expr_to_str(right);
 152 
 153         snprintf(buf, sizeof(buf), "%s %s %s %s", get_filename(), get_function(),
 154                  left_name, right_name);
 155         tag = str_to_mtag(buf);
 156         tag_sval.type = estate_type(state);
 157         tag_sval.uvalue = tag;
 158 
 159         rl = rl_filter(estate_rl(state), valid_ptr_rl);
 160         rl = clone_rl(rl);
 161         add_range(&rl, tag_sval, tag_sval);
 162 
 163         update_mtag_info(expr, tag, left_name, buf, state);
 164 
 165         free_string(left_name);
 166         free_string(right_name);
 167 
 168         return alloc_estate_rl(rl);
 169 }
 170 
 171 int get_string_mtag(struct expression *expr, mtag_t *tag)
 172 {
 173         mtag_t xor;
 174 
 175         if (expr->type != EXPR_STRING || !expr->string)
 176                 return 0;
 177 
 178         /* I was worried about collisions so I added a xor */
 179         xor = str_to_mtag("__smatch string");
 180         *tag = str_to_mtag(expr->string->data);
 181         *tag = *tag ^ xor;
 182 
 183         return 1;