Print this page
12257 resync smatch to 0.6.1-rc1-il-4


  33  *
  34  * Another place where we would maybe name the pointer is when they are passed
  35  * to the probe().  Because that's an important pointer, since there is one
  36  * per driver (sort of).
  37  *
  38  * My vision is that you could take a pointer and trace it back to a global.  So
  39  * I'm going to track that pointer_tag - 28 bytes takes you to another pointer
  40  * tag.  You could follow that one back and so on.  Also when we pass a pointer
  41  * to a function that would be recorded as sort of a link or path or something.
  42  *
  43  */
  44 
  45 #include "smatch.h"
  46 #include "smatch_slist.h"
  47 #include "smatch_extra.h"
  48 
  49 #include <openssl/md5.h>
  50 
  51 static int my_id;
  52 
  53 static mtag_t str_to_tag(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;


 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_tag(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_tag("__smatch string");
 160         *tag = str_to_tag(expr->string->data);
 161         *tag = *tag ^ xor;
 162 
 163         return 1;
 164 }
 165 
 166 int get_toplevel_mtag(struct symbol *sym, mtag_t *tag)
 167 {
 168         char buf[256];
 169 
 170         if (!sym)
 171                 return 0;
 172 
 173         if (!sym->ident ||
 174             !(sym->ctype.modifiers & MOD_TOPLEVEL))
 175                 return 0;
 176 
 177         snprintf(buf, sizeof(buf), "%s %s",
 178                  (sym->ctype.modifiers & MOD_STATIC) ? get_filename() : "extern",
 179                  sym->ident->name);
 180         *tag = str_to_tag(buf);
 181         return 1;
 182 }
 183 
 184 bool get_symbol_mtag(struct symbol *sym, mtag_t *tag)
 185 {
 186         char buf[256];
 187 
 188         if (!sym || !sym->ident)
 189                 return false;
 190 
 191         if (get_toplevel_mtag(sym, tag))
 192                 return true;
 193 
 194         if (get_param_num_from_sym(sym) >= 0)
 195                 return false;
 196 
 197         snprintf(buf, sizeof(buf), "%s %s %s",
 198                  get_filename(), get_function(), sym->ident->name);
 199         *tag = str_to_tag(buf);
 200         return true;
 201 }
 202 
 203 static void global_variable(struct symbol *sym)
 204 {
 205         mtag_t tag;
 206 
 207         if (!get_toplevel_mtag(sym, &tag))
 208                 return;
 209 
 210         sql_insert_mtag_about(tag,
 211                               sym->ident->name,
 212                               (sym->ctype.modifiers & MOD_STATIC) ? get_filename() : "extern");
 213 }
 214 
 215 static int get_array_mtag_offset(struct expression *expr, mtag_t *tag, int *offset)
 216 {
 217         struct expression *array, *offset_expr;
 218         struct symbol *type;
 219         sval_t sval;


 241         *offset = start_offset + sval.value * type_bytes(type);
 242 
 243         return 1;
 244 }
 245 
 246 struct range_list *swap_mtag_seed(struct expression *expr, struct range_list *rl)
 247 {
 248         char buf[256];
 249         char *name;
 250         sval_t sval;
 251         mtag_t tag;
 252 
 253         if (!rl_to_sval(rl, &sval))
 254                 return rl;
 255         if (sval.type->type != SYM_PTR || sval.uvalue != MTAG_SEED)
 256                 return rl;
 257 
 258         name = expr_to_str(expr);
 259         snprintf(buf, sizeof(buf), "%s %s %s", get_filename(), get_function(), name);
 260         free_string(name);
 261         tag = str_to_tag(buf);
 262         sval.value = tag;
 263         return alloc_rl(sval, sval);
 264 }
 265 
 266 int create_mtag_alias(mtag_t tag, struct expression *expr, mtag_t *new)
 267 {
 268         char buf[256];
 269         int lines_from_start;
 270         char *str;
 271 
 272         /*
 273          * We need the alias to be unique.  It's not totally required that it
 274          * be the same from one DB build to then next, but it makes debugging
 275          * a bit simpler.
 276          *
 277          */
 278 
 279         if (!cur_func_sym)
 280                 return 0;
 281 
 282         lines_from_start = expr->pos.line - cur_func_sym->pos.line;
 283         str = expr_to_str(expr);
 284         snprintf(buf, sizeof(buf), "%lld %d %s", tag, lines_from_start, str);
 285         free_string(str);
 286 
 287         *new = str_to_tag(buf);
 288         sql_insert_mtag_alias(tag, *new);
 289 
 290         return 1;
 291 }
 292 
 293 static int get_implied_mtag_offset(struct expression *expr, mtag_t *tag, int *offset)
 294 {
 295         struct smatch_state *state;
 296         struct symbol *type;
 297         sval_t sval;
 298 
 299         type = get_type(expr);
 300         if (!type_is_ptr(type))
 301                 return 0;
 302         state = get_extra_state(expr);
 303         if (!state || !estate_get_single_value(state, &sval) || sval.value == 0)
 304                 return 0;
 305 
 306         *tag = sval.uvalue & ~MTAG_OFFSET_MASK;
 307         *offset = sval.uvalue & MTAG_OFFSET_MASK;




  33  *
  34  * Another place where we would maybe name the pointer is when they are passed
  35  * to the probe().  Because that's an important pointer, since there is one
  36  * per driver (sort of).
  37  *
  38  * My vision is that you could take a pointer and trace it back to a global.  So
  39  * I'm going to track that pointer_tag - 28 bytes takes you to another pointer
  40  * tag.  You could follow that one back and so on.  Also when we pass a pointer
  41  * to a function that would be recorded as sort of a link or path or something.
  42  *
  43  */
  44 
  45 #include "smatch.h"
  46 #include "smatch_slist.h"
  47 #include "smatch_extra.h"
  48 
  49 #include <openssl/md5.h>
  50 
  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;


 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;
 164 }
 165 
 166 int get_toplevel_mtag(struct symbol *sym, mtag_t *tag)
 167 {
 168         char buf[256];
 169 
 170         if (!sym)
 171                 return 0;
 172 
 173         if (!sym->ident ||
 174             !(sym->ctype.modifiers & MOD_TOPLEVEL))
 175                 return 0;
 176 
 177         snprintf(buf, sizeof(buf), "%s %s",
 178                  (sym->ctype.modifiers & MOD_STATIC) ? get_filename() : "extern",
 179                  sym->ident->name);
 180         *tag = str_to_mtag(buf);
 181         return 1;
 182 }
 183 
 184 bool get_symbol_mtag(struct symbol *sym, mtag_t *tag)
 185 {
 186         char buf[256];
 187 
 188         if (!sym || !sym->ident)
 189                 return false;
 190 
 191         if (get_toplevel_mtag(sym, tag))
 192                 return true;
 193 
 194         if (get_param_num_from_sym(sym) >= 0)
 195                 return false;
 196 
 197         snprintf(buf, sizeof(buf), "%s %s %s",
 198                  get_filename(), get_function(), sym->ident->name);
 199         *tag = str_to_mtag(buf);
 200         return true;
 201 }
 202 
 203 static void global_variable(struct symbol *sym)
 204 {
 205         mtag_t tag;
 206 
 207         if (!get_toplevel_mtag(sym, &tag))
 208                 return;
 209 
 210         sql_insert_mtag_about(tag,
 211                               sym->ident->name,
 212                               (sym->ctype.modifiers & MOD_STATIC) ? get_filename() : "extern");
 213 }
 214 
 215 static int get_array_mtag_offset(struct expression *expr, mtag_t *tag, int *offset)
 216 {
 217         struct expression *array, *offset_expr;
 218         struct symbol *type;
 219         sval_t sval;


 241         *offset = start_offset + sval.value * type_bytes(type);
 242 
 243         return 1;
 244 }
 245 
 246 struct range_list *swap_mtag_seed(struct expression *expr, struct range_list *rl)
 247 {
 248         char buf[256];
 249         char *name;
 250         sval_t sval;
 251         mtag_t tag;
 252 
 253         if (!rl_to_sval(rl, &sval))
 254                 return rl;
 255         if (sval.type->type != SYM_PTR || sval.uvalue != MTAG_SEED)
 256                 return rl;
 257 
 258         name = expr_to_str(expr);
 259         snprintf(buf, sizeof(buf), "%s %s %s", get_filename(), get_function(), name);
 260         free_string(name);
 261         tag = str_to_mtag(buf);
 262         sval.value = tag;
 263         return alloc_rl(sval, sval);
 264 }
 265 
 266 int create_mtag_alias(mtag_t tag, struct expression *expr, mtag_t *new)
 267 {
 268         char buf[256];
 269         int lines_from_start;
 270         char *str;
 271 
 272         /*
 273          * We need the alias to be unique.  It's not totally required that it
 274          * be the same from one DB build to then next, but it makes debugging
 275          * a bit simpler.
 276          *
 277          */
 278 
 279         if (!cur_func_sym)
 280                 return 0;
 281 
 282         lines_from_start = expr->pos.line - cur_func_sym->pos.line;
 283         str = expr_to_str(expr);
 284         snprintf(buf, sizeof(buf), "%lld %d %s", tag, lines_from_start, str);
 285         free_string(str);
 286 
 287         *new = str_to_mtag(buf);
 288         sql_insert_mtag_alias(tag, *new);
 289 
 290         return 1;
 291 }
 292 
 293 static int get_implied_mtag_offset(struct expression *expr, mtag_t *tag, int *offset)
 294 {
 295         struct smatch_state *state;
 296         struct symbol *type;
 297         sval_t sval;
 298 
 299         type = get_type(expr);
 300         if (!type_is_ptr(type))
 301                 return 0;
 302         state = get_extra_state(expr);
 303         if (!state || !estate_get_single_value(state, &sval) || sval.value == 0)
 304                 return 0;
 305 
 306         *tag = sval.uvalue & ~MTAG_OFFSET_MASK;
 307         *offset = sval.uvalue & MTAG_OFFSET_MASK;