Print this page
11506 smatch resync

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/smatch_kernel_user_data.c
          +++ new/usr/src/tools/smatch/src/smatch_kernel_user_data.c
↓ open down ↓ 24 lines elided ↑ open up ↑
  25   25  #include "smatch.h"
  26   26  #include "smatch_slist.h"
  27   27  #include "smatch_extra.h"
  28   28  
  29   29  static int my_id;
  30   30  static int my_call_id;
  31   31  
  32   32  STATE(called);
  33   33  static bool func_gets_user_data;
  34   34  
  35      -static const char * kstr_funcs[] = {
       35 +static const char *kstr_funcs[] = {
  36   36          "kstrtoull", "kstrtoll", "kstrtoul", "kstrtol", "kstrtouint",
  37   37          "kstrtoint", "kstrtou64", "kstrtos64", "kstrtou32", "kstrtos32",
  38   38          "kstrtou16", "kstrtos16", "kstrtou8", "kstrtos8", "kstrtoull_from_user"
  39   39          "kstrtoll_from_user", "kstrtoul_from_user", "kstrtol_from_user",
  40   40          "kstrtouint_from_user", "kstrtoint_from_user", "kstrtou16_from_user",
  41   41          "kstrtos16_from_user", "kstrtou8_from_user", "kstrtos8_from_user",
  42   42          "kstrtou64_from_user", "kstrtos64_from_user", "kstrtou32_from_user",
  43   43          "kstrtos32_from_user",
  44   44  };
  45   45  
  46   46  static const char *returns_user_data[] = {
  47   47          "simple_strtol", "simple_strtoll", "simple_strtoul", "simple_strtoull",
  48      -        "kvm_register_read", "nlmsg_data", "nla_data", "memdup_user",
  49      -        "kmap_atomic", "skb_network_header",
       48 +        "kvm_register_read",
  50   49  };
  51   50  
       51 +static const char *returns_pointer_to_user_data[] = {
       52 +        "nlmsg_data", "nla_data", "memdup_user", "kmap_atomic", "skb_network_header",
       53 +};
       54 +
  52   55  static void set_points_to_user_data(struct expression *expr);
  53   56  
  54   57  static struct stree *start_states;
  55   58  static struct stree_stack *saved_stack;
  56   59  static void save_start_states(struct statement *stmt)
  57   60  {
  58   61          start_states = clone_stree(__get_cur_stree());
  59   62  }
  60   63  
  61   64  static void free_start_states(void)
↓ open down ↓ 15 lines elided ↑ open up ↑
  77   80  
  78   81  static struct smatch_state *empty_state(struct sm_state *sm)
  79   82  {
  80   83          return alloc_estate_empty();
  81   84  }
  82   85  
  83   86  static void pre_merge_hook(struct sm_state *sm)
  84   87  {
  85   88          struct smatch_state *user;
  86   89          struct smatch_state *extra;
       90 +        struct smatch_state *state;
  87   91          struct range_list *rl;
  88   92          sval_t dummy;
  89   93          sval_t sval_100;
  90   94  
  91   95          sval_100.value = 100;
  92   96          sval_100.type = &int_ctype;
  93   97  
  94      -        user = get_state(my_id, sm->name, sm->sym);
  95      -        if (!user)
       98 +        user = __get_state(my_id, sm->name, sm->sym);
       99 +        if (!user || !estate_rl(user))
  96  100                  return;
  97      -        if (!__in_function_def && !estate_rl(sm->state)) {
  98      -                /*
  99      -                 * If the one side is capped and the other side is empty then
 100      -                 * let's just mark it as not-user data because the information
 101      -                 * isn't going to be useful.  How this looks is:
 102      -                 *
 103      -                 * if (user_var > trusted)
 104      -                 *      user_var = trusted;  <-- empty state
 105      -                 * else
 106      -                 *      <-- capped
 107      -                 *
 108      -                 * The problem is that sometimes things are capped to a literal
 109      -                 * and we'd like to keep the state in that case...  Ugh.  I've
 110      -                 * added a check which assumes that everything less than 100 is
 111      -                 * probably capped against a literal.
 112      -                 *
 113      -                 */
 114      -                if (is_capped_var_sym(sm->name, sm->sym) &&
 115      -                    sval_cmp(estate_max(user), sval_100) > 0)
 116      -                        set_state(my_id, sm->name, sm->sym, alloc_estate_empty());
      101 +        extra = __get_state(SMATCH_EXTRA, sm->name, sm->sym);
      102 +        if (!extra)
 117  103                  return;
 118      -        }
 119      -        extra = get_state(SMATCH_EXTRA, sm->name, sm->sym);
 120      -        if (!extra || !estate_rl(extra))
 121      -                return;
 122  104          rl = rl_intersection(estate_rl(user), estate_rl(extra));
 123  105          if (rl_to_sval(rl, &dummy))
 124  106                  rl = NULL;
 125      -        set_state(my_id, sm->name, sm->sym, alloc_estate_rl(clone_rl(rl)));
      107 +        state = alloc_estate_rl(clone_rl(rl));
      108 +        if (estate_capped(user) || is_capped_var_sym(sm->name, sm->sym))
      109 +                estate_set_capped(state);
      110 +        set_state(my_id, sm->name, sm->sym, state);
 126  111  }
 127  112  
 128  113  static void extra_nomod_hook(const char *name, struct symbol *sym, struct expression *expr, struct smatch_state *state)
 129  114  {
 130      -        struct smatch_state *user;
      115 +        struct smatch_state *user, *new;
 131  116          struct range_list *rl;
 132  117  
 133      -        user = get_state(my_id, name, sym);
      118 +        user = __get_state(my_id, name, sym);
 134  119          if (!user)
 135  120                  return;
 136  121          rl = rl_intersection(estate_rl(user), estate_rl(state));
 137  122          if (rl_equiv(rl, estate_rl(user)))
 138  123                  return;
 139      -        set_state(my_id, name, sym, alloc_estate_rl(rl));
      124 +        new = alloc_estate_rl(rl);
      125 +        if (estate_capped(user))
      126 +                estate_set_capped(new);
      127 +        set_state(my_id, name, sym, new);
 140  128  }
 141  129  
      130 +static bool binop_capped(struct expression *expr)
      131 +{
      132 +        struct range_list *left_rl;
      133 +        int comparison;
      134 +
      135 +        if (expr->op == '-' && get_user_rl(expr->left, &left_rl)) {
      136 +                if (user_rl_capped(expr->left))
      137 +                        return true;
      138 +                comparison = get_comparison(expr->left, expr->right);
      139 +                if (comparison && show_special(comparison)[0] == '>')
      140 +                        return true;
      141 +                return false;
      142 +        }
      143 +
      144 +        if (expr->op == '&' || expr->op == '%') {
      145 +                if (is_capped(expr->left) || is_capped(expr->right))
      146 +                        return true;
      147 +                if (user_rl_capped(expr->left) || user_rl_capped(expr->right))
      148 +                        return true;
      149 +                return false;
      150 +        }
      151 +
      152 +        if (user_rl_capped(expr->left) &&
      153 +            user_rl_capped(expr->right))
      154 +                return true;
      155 +        return false;
      156 +}
      157 +
      158 +bool user_rl_capped(struct expression *expr)
      159 +{
      160 +        struct smatch_state *state;
      161 +        struct range_list *rl;
      162 +        sval_t sval;
      163 +
      164 +        expr = strip_expr(expr);
      165 +        if (!expr)
      166 +                return false;
      167 +        if (get_value(expr, &sval))
      168 +                return true;
      169 +        if (expr->type == EXPR_BINOP)
      170 +                return binop_capped(expr);
      171 +        if ((expr->type == EXPR_PREOP || expr->type == EXPR_POSTOP) &&
      172 +            (expr->op == SPECIAL_INCREMENT || expr->op == SPECIAL_DECREMENT))
      173 +                return user_rl_capped(expr->unop);
      174 +        state = get_state_expr(my_id, expr);
      175 +        if (state)
      176 +                return estate_capped(state);
      177 +
      178 +        if (get_user_rl(expr, &rl))
      179 +                return false;  /* uncapped user data */
      180 +
      181 +        return true;  /* not actually user data */
      182 +}
      183 +
 142  184  static void tag_inner_struct_members(struct expression *expr, struct symbol *member)
 143  185  {
 144  186          struct expression *edge_member;
 145  187          struct symbol *base = get_real_base_type(member);
 146  188          struct symbol *tmp;
 147  189  
 148  190          if (member->ident)
 149  191                  expr = member_expression(expr, '.', member->ident);
 150  192  
 151  193          FOR_EACH_PTR(base->symbol_list, tmp) {
↓ open down ↓ 188 lines elided ↑ open up ↑
 340  382                  return 0;
 341  383          sym = get_real_base_type(sym);
 342  384          if (!sym || sym->type != SYM_STRUCT || !sym->ident)
 343  385                  return 0;
 344  386          if (strcmp(sym->ident->name, "sk_buff") != 0)
 345  387                  return 0;
 346  388  
 347  389          return 1;
 348  390  }
 349  391  
      392 +static bool is_points_to_user_data_fn(struct expression *expr)
      393 +{
      394 +        int i;
      395 +
      396 +        expr = strip_expr(expr);
      397 +        if (expr->type != EXPR_CALL || expr->fn->type != EXPR_SYMBOL ||
      398 +            !expr->fn->symbol)
      399 +                return false;
      400 +        expr = expr->fn;
      401 +        for (i = 0; i < ARRAY_SIZE(returns_pointer_to_user_data); i++) {
      402 +                if (sym_name_is(returns_pointer_to_user_data[i], expr))
      403 +                        return true;
      404 +        }
      405 +        return false;
      406 +}
      407 +
 350  408  static int get_rl_from_function(struct expression *expr, struct range_list **rl)
 351  409  {
 352  410          int i;
 353  411  
 354  412          if (expr->type != EXPR_CALL || expr->fn->type != EXPR_SYMBOL ||
 355  413              !expr->fn->symbol_name || !expr->fn->symbol_name->name)
 356  414                  return 0;
 357  415  
 358  416          for (i = 0; i < ARRAY_SIZE(returns_user_data); i++) {
 359  417                  if (strcmp(expr->fn->symbol_name->name, returns_user_data[i]) == 0) {
↓ open down ↓ 11 lines elided ↑ open up ↑
 371  429          char buf[256];
 372  430          struct symbol *sym;
 373  431          char *name;
 374  432          int ret = 0;
 375  433  
 376  434          expr = strip_expr(expr);
 377  435          if (!expr)
 378  436                  return 0;
 379  437          if (is_skb_data(expr))
 380  438                  return 1;
      439 +        if (is_points_to_user_data_fn(expr))
      440 +                return 1;
 381  441          if (get_rl_from_function(expr, &rl))
 382  442                  return 1;
 383  443  
 384  444          if (expr->type == EXPR_BINOP && expr->op == '+') {
 385  445                  if (points_to_user_data(expr->left))
 386  446                          return 1;
 387  447                  if (points_to_user_data(expr->right))
 388  448                          return 1;
 389  449                  return 0;
 390  450          }
 391  451  
 392  452          name = expr_to_var_sym(expr, &sym);
 393  453          if (!name || !sym)
 394  454                  goto free;
 395  455          snprintf(buf, sizeof(buf), "*%s", name);
 396      -        state = get_state(my_id, buf, sym);
      456 +        state = __get_state(my_id, buf, sym);
 397  457          if (state && estate_rl(state))
 398  458                  ret = 1;
 399  459  free:
 400  460          free_string(name);
 401  461          return ret;
 402  462  }
 403  463  
 404  464  static void set_points_to_user_data(struct expression *expr)
 405  465  {
 406  466          char *name;
 407  467          struct symbol *sym;
 408  468          char buf[256];
      469 +        struct symbol *type;
 409  470  
 410  471          name = expr_to_var_sym(expr, &sym);
 411  472          if (!name || !sym)
 412  473                  goto free;
 413  474          snprintf(buf, sizeof(buf), "*%s", name);
 414      -        set_state(my_id, buf, sym, alloc_estate_whole(&llong_ctype));
      475 +        type = get_type(expr);
      476 +        if (type && type->type == SYM_PTR)
      477 +                type = get_real_base_type(type);
      478 +        if (!type || type->type != SYM_BASETYPE)
      479 +                type = &llong_ctype;
      480 +        set_state(my_id, buf, sym, alloc_estate_whole(type));
 415  481  free:
 416  482          free_string(name);
 417  483  }
 418  484  
 419  485  static int comes_from_skb_data(struct expression *expr)
 420  486  {
 421  487          expr = strip_expr(expr);
 422  488          if (!expr || expr->type != EXPR_PREOP || expr->op != '*')
 423  489                  return 0;
 424  490  
↓ open down ↓ 57 lines elided ↑ open up ↑
 482  548          name = expr_to_var(expr->right);
 483  549          if (!name || strcmp(name, "__val_gu") != 0)
 484  550                  goto free;
 485  551          set_state_expr(my_id, expr->left, alloc_estate_whole(get_type(expr->left)));
 486  552          ret = 1;
 487  553  free:
 488  554          free_string(name);
 489  555          return ret;
 490  556  }
 491  557  
      558 +static bool handle_op_assign(struct expression *expr)
      559 +{
      560 +        struct expression *binop_expr;
      561 +        struct smatch_state *state;
      562 +        struct range_list *rl;
      563 +
      564 +        switch (expr->op) {
      565 +        case SPECIAL_ADD_ASSIGN:
      566 +        case SPECIAL_SUB_ASSIGN:
      567 +        case SPECIAL_AND_ASSIGN:
      568 +        case SPECIAL_MOD_ASSIGN:
      569 +        case SPECIAL_SHL_ASSIGN:
      570 +        case SPECIAL_SHR_ASSIGN:
      571 +        case SPECIAL_OR_ASSIGN:
      572 +        case SPECIAL_XOR_ASSIGN:
      573 +        case SPECIAL_MUL_ASSIGN:
      574 +        case SPECIAL_DIV_ASSIGN:
      575 +                binop_expr = binop_expression(expr->left,
      576 +                                              op_remove_assign(expr->op),
      577 +                                              expr->right);
      578 +                if (!get_user_rl(binop_expr, &rl))
      579 +                        return true;
      580 +
      581 +                rl = cast_rl(get_type(expr->left), rl);
      582 +                state = alloc_estate_rl(rl);
      583 +                if (user_rl_capped(binop_expr))
      584 +                        estate_set_capped(state);
      585 +                set_state_expr(my_id, expr->left, state);
      586 +                return true;
      587 +        }
      588 +        return false;
      589 +}
      590 +
 492  591  static void match_assign(struct expression *expr)
 493  592  {
 494  593          struct range_list *rl;
      594 +        static struct expression *handled;
      595 +        struct smatch_state *state;
      596 +        struct expression *faked;
 495  597  
      598 +        faked = get_faked_expression();
      599 +        if (faked && faked == handled)
      600 +                return;
 496  601          if (is_fake_call(expr->right))
 497  602                  goto clear_old_state;
 498  603          if (handle_get_user(expr))
 499  604                  return;
 500      -        if (points_to_user_data(expr->right))
      605 +        if (points_to_user_data(expr->right)) {
      606 +                handled = expr;
 501  607                  set_points_to_user_data(expr->left);
      608 +        }
 502  609          if (handle_struct_assignment(expr))
 503  610                  return;
 504  611  
      612 +        if (handle_op_assign(expr))
      613 +                return;
      614 +        if (expr->op != '=')
      615 +                goto clear_old_state;
      616 +
      617 +        /* Handled by DB code */
      618 +        if (expr->right->type == EXPR_CALL || __in_fake_parameter_assign)
      619 +                return;
      620 +
 505  621          if (!get_user_rl(expr->right, &rl))
 506  622                  goto clear_old_state;
 507  623  
 508  624          rl = cast_rl(get_type(expr->left), rl);
 509      -        set_state_expr(my_id, expr->left, alloc_estate_rl(rl));
      625 +        state = alloc_estate_rl(rl);
      626 +        if (user_rl_capped(expr->right))
      627 +                estate_set_capped(state);
      628 +        set_state_expr(my_id, expr->left, state);
 510  629  
 511  630          return;
 512  631  
 513  632  clear_old_state:
 514  633          if (get_state_expr(my_id, expr->left))
 515  634                  set_state_expr(my_id, expr->left, alloc_estate_empty());
 516  635  }
 517  636  
 518  637  static void handle_eq_noteq(struct expression *expr)
 519  638  {
↓ open down ↓ 11 lines elided ↑ open up ↑
 531  650                  set_true_false_states_expr(my_id, expr->left,
 532  651                                  expr->op == SPECIAL_EQUAL ? alloc_estate_empty() : NULL,
 533  652                                  expr->op == SPECIAL_EQUAL ? NULL : alloc_estate_empty());
 534  653          } else {
 535  654                  set_true_false_states_expr(my_id, expr->right,
 536  655                                  expr->op == SPECIAL_EQUAL ? alloc_estate_empty() : NULL,
 537  656                                  expr->op == SPECIAL_EQUAL ? NULL : alloc_estate_empty());
 538  657          }
 539  658  }
 540  659  
 541      -static void handle_unsigned_lt_gt(struct expression *expr)
      660 +static struct range_list *strip_negatives(struct range_list *rl)
 542  661  {
      662 +        sval_t min = rl_min(rl);
      663 +        sval_t minus_one;
      664 +        sval_t over;
      665 +        sval_t max = sval_type_max(rl_type(rl));
      666 +
      667 +        minus_one.type = rl_type(rl);
      668 +        minus_one.value = INT_MAX + 1ULL;
      669 +        over.type = rl_type(rl);
      670 +        over.value = -1;
      671 +
      672 +        if (!rl)
      673 +                return NULL;
      674 +
      675 +        if (type_unsigned(rl_type(rl)) && type_bits(rl_type(rl)) > 31)
      676 +                return remove_range(rl, over, max);
      677 +
      678 +        return remove_range(rl, min, minus_one);
      679 +}
      680 +
      681 +static void handle_compare(struct expression *expr)
      682 +{
      683 +        struct expression  *left, *right;
      684 +        struct range_list *left_rl = NULL;
      685 +        struct range_list *right_rl = NULL;
      686 +        struct range_list *user_rl;
      687 +        struct smatch_state *capped_state;
      688 +        struct smatch_state *left_true = NULL;
      689 +        struct smatch_state *left_false = NULL;
      690 +        struct smatch_state *right_true = NULL;
      691 +        struct smatch_state *right_false = NULL;
 543  692          struct symbol *type;
 544      -        struct range_list *left;
 545      -        struct range_list *right;
 546      -        struct range_list *non_negative;
 547      -        sval_t min, minus_one;
      693 +        sval_t sval;
 548  694  
      695 +        left = strip_expr(expr->left);
      696 +        right = strip_expr(expr->right);
      697 +
      698 +        while (left->type == EXPR_ASSIGNMENT)
      699 +                left = strip_expr(left->left);
      700 +
 549  701          /*
 550      -         * conditions are mostly handled by smatch_extra.c.  The special case
 551      -         * here is that say you have if (user_int < unknown_u32) {
 552      -         * In Smatch extra we say that, We have no idea what value
 553      -         * unknown_u32 is so the only thin we can say for sure is that
 554      -         * user_int is not -1 (UINT_MAX).  But in check_user_data2.c we should
 555      -         * assume that unless unknown_u32 is user data, it's probably less than
 556      -         * INT_MAX.
      702 +         * Conditions are mostly handled by smatch_extra.c, but there are some
      703 +         * times where the exact values are not known so we can't do that.
 557  704           *
      705 +         * Normally, we might consider using smatch_capped.c to supliment smatch
      706 +         * extra but that doesn't work when we merge unknown uncapped kernel
      707 +         * data with unknown capped user data.  The result is uncapped user
      708 +         * data.  We need to keep it separate and say that the user data is
      709 +         * capped.  In the past, I would have marked this as just regular
      710 +         * kernel data (not user data) but we can't do that these days because
      711 +         * we need to track user data for Spectre.
      712 +         *
      713 +         * The other situation which we have to handle is when we do have an
      714 +         * int and we compare against an unknown unsigned kernel variable.  In
      715 +         * that situation we assume that the kernel data is less than INT_MAX.
      716 +         * Otherwise then we get all sorts of array underflow false positives.
      717 +         *
 558  718           */
 559  719  
 560      -        type = get_type(expr);
 561      -        if (!type_unsigned(type))
      720 +        /* Handled in smatch_extra.c */
      721 +        if (get_implied_value(left, &sval) ||
      722 +            get_implied_value(right, &sval))
 562  723                  return;
 563  724  
 564      -        /*
 565      -         * Assume if (user < trusted) { ... because I am lazy and because this
 566      -         * is the correct way to write code.
 567      -         */
 568      -        if (!get_user_rl(expr->left, &left))
      725 +        get_user_rl(left, &left_rl);
      726 +        get_user_rl(right, &right_rl);
      727 +
      728 +        /* nothing to do */
      729 +        if (!left_rl && !right_rl)
 569  730                  return;
 570      -        if (get_user_rl(expr->right, &right))
      731 +        /* if both sides are user data that's not a good limit */
      732 +        if (left_rl && right_rl)
 571  733                  return;
 572  734  
 573      -        if (!sval_is_negative(rl_min(left)))
 574      -                return;
 575      -        min = rl_min(left);
 576      -        minus_one.type = rl_type(left);
 577      -        minus_one.value = -1;
 578      -        non_negative = remove_range(left, min, minus_one);
      735 +        if (left_rl)
      736 +                user_rl = left_rl;
      737 +        else
      738 +                user_rl = right_rl;
 579  739  
      740 +        type = get_type(expr);
      741 +        if (type_unsigned(type))
      742 +                user_rl = strip_negatives(user_rl);
      743 +        capped_state = alloc_estate_rl(user_rl);
      744 +        estate_set_capped(capped_state);
      745 +
 580  746          switch (expr->op) {
 581  747          case '<':
 582  748          case SPECIAL_UNSIGNED_LT:
 583  749          case SPECIAL_LTE:
 584  750          case SPECIAL_UNSIGNED_LTE:
 585      -                set_true_false_states_expr(my_id, expr->left,
 586      -                                           alloc_estate_rl(non_negative), NULL);
      751 +                if (left_rl)
      752 +                        left_true = capped_state;
      753 +                else
      754 +                        right_false = capped_state;
 587  755                  break;
 588  756          case '>':
 589  757          case SPECIAL_UNSIGNED_GT:
 590  758          case SPECIAL_GTE:
 591  759          case SPECIAL_UNSIGNED_GTE:
 592      -                set_true_false_states_expr(my_id, expr->left,
 593      -                                           NULL, alloc_estate_rl(non_negative));
      760 +                if (left_rl)
      761 +                        left_false = capped_state;
      762 +                else
      763 +                        right_true = capped_state;
 594  764                  break;
 595  765          }
      766 +
      767 +        set_true_false_states_expr(my_id, left, left_true, left_false);
      768 +        set_true_false_states_expr(my_id, right, right_true, right_false);
 596  769  }
 597  770  
 598  771  static void match_condition(struct expression *expr)
 599  772  {
 600  773          if (expr->type != EXPR_COMPARE)
 601  774                  return;
 602  775  
 603  776          if (expr->op == SPECIAL_EQUAL ||
 604  777              expr->op == SPECIAL_NOTEQUAL) {
 605  778                  handle_eq_noteq(expr);
 606  779                  return;
 607  780          }
 608  781  
 609      -        handle_unsigned_lt_gt(expr);
      782 +        handle_compare(expr);
 610  783  }
 611  784  
 612  785  static void match_user_assign_function(const char *fn, struct expression *expr, void *unused)
 613  786  {
 614  787          tag_as_user_data(expr->left);
 615  788          set_points_to_user_data(expr->left);
 616  789  }
 617  790  
 618  791  static void match_returns_user_rl(const char *fn, struct expression *expr, void *unused)
 619  792  {
↓ open down ↓ 27 lines elided ↑ open up ↑
 647  820                  *rl = alloc_whole_rl(&uint_ctype);
 648  821                  return 1;
 649  822          }
 650  823          if (strcmp(macro, "ntohs") == 0) {
 651  824                  *rl = alloc_whole_rl(&ushort_ctype);
 652  825                  return 1;
 653  826          }
 654  827          return 0;
 655  828  }
 656  829  
 657      -struct db_info {
 658      -        struct range_list *rl;
 659      -        struct expression *call;
 660      -};
 661      -static int returned_rl_callback(void *_info, int argc, char **argv, char **azColName)
 662      -{
 663      -        struct db_info *db_info = _info;
 664      -        struct range_list *rl;
 665      -        char *return_ranges = argv[0];
 666      -        char *user_ranges = argv[1];
 667      -        struct expression *arg;
 668      -        int comparison;
 669      -
 670      -        if (argc != 2)
 671      -                return 0;
 672      -
 673      -        call_results_to_rl(db_info->call, get_type(db_info->call), user_ranges, &rl);
 674      -        if (str_to_comparison_arg(return_ranges, db_info->call, &comparison, &arg) &&
 675      -            comparison == SPECIAL_EQUAL) {
 676      -                struct range_list *orig_rl;
 677      -
 678      -                if (!get_user_rl(arg, &orig_rl))
 679      -                        return 0;
 680      -                rl = rl_intersection(rl, orig_rl);
 681      -                if (!rl)
 682      -                        return 0;
 683      -        }
 684      -        db_info->rl = rl_union(db_info->rl, rl);
 685      -
 686      -        return 0;
 687      -}
 688      -
 689  830  static int has_user_data(struct symbol *sym)
 690  831  {
 691  832          struct sm_state *tmp;
 692  833  
 693  834          FOR_EACH_MY_SM(my_id, __get_cur_stree(), tmp) {
 694  835                  if (tmp->sym == sym)
 695  836                          return 1;
 696  837          } END_FOR_EACH_SM(tmp);
 697  838          return 0;
 698  839  }
↓ open down ↓ 9 lines elided ↑ open up ↑
 708  849                          continue;
 709  850                  if (has_user_data(sym))
 710  851                          return 1;
 711  852          } END_FOR_EACH_PTR(arg);
 712  853  
 713  854          return 0;
 714  855  }
 715  856  
 716  857  static int db_returned_user_rl(struct expression *call, struct range_list **rl)
 717  858  {
 718      -        struct db_info db_info = {};
      859 +        struct smatch_state *state;
      860 +        char buf[48];
 719  861  
 720      -        /* for function pointers assume everything is used */
 721      -        if (call->fn->type != EXPR_SYMBOL)
 722      -                return 0;
 723  862          if (is_fake_call(call))
 724  863                  return 0;
 725      -
 726      -        db_info.call = call;
 727      -        run_sql(&returned_rl_callback, &db_info,
 728      -                "select return, value from return_states where %s and type = %d and parameter = -1 and key = '$';",
 729      -                get_static_filter(call->fn->symbol), USER_DATA3_SET);
 730      -        if (db_info.rl) {
 731      -                func_gets_user_data = true;
 732      -                *rl = db_info.rl;
 733      -                return 1;
 734      -        }
 735      -
 736      -        run_sql(&returned_rl_callback, &db_info,
 737      -                "select return, value from return_states where %s and type = %d and parameter = -1 and key = '$';",
 738      -                get_static_filter(call->fn->symbol), USER_DATA3);
 739      -        if (db_info.rl) {
 740      -                if (!we_pass_user_data(call))
 741      -                        return 0;
 742      -                *rl = db_info.rl;
 743      -                return 1;
 744      -        }
 745      -
 746      -        return 0;
      864 +        snprintf(buf, sizeof(buf), "return %p", call);
      865 +        state = get_state(my_id, buf, NULL);
      866 +        if (!state || !estate_rl(state))
      867 +                return 0;
      868 +        *rl = estate_rl(state);
      869 +        return 1;
 747  870  }
 748  871  
 749  872  struct stree *get_user_stree(void)
 750  873  {
 751  874          return get_all_states_stree(my_id);
 752  875  }
 753  876  
 754  877  static int user_data_flag;
 755  878  static int no_user_data_flag;
 756      -static struct range_list *var_user_rl(struct expression *expr)
      879 +struct range_list *var_user_rl(struct expression *expr)
 757  880  {
 758  881          struct smatch_state *state;
 759  882          struct range_list *rl;
 760  883          struct range_list *absolute_rl;
 761  884  
      885 +        if (expr->type == EXPR_PREOP && expr->op == '&') {
      886 +                no_user_data_flag = 1;
      887 +                return NULL;
      888 +        }
      889 +
 762  890          if (expr->type == EXPR_BINOP && expr->op == '%') {
 763  891                  struct range_list *left, *right;
 764  892  
 765  893                  if (!get_user_rl(expr->right, &right))
 766  894                          return NULL;
 767  895                  get_absolute_rl(expr->left, &left);
 768  896                  rl = rl_binop(left, '%', right);
 769  897                  goto found;
 770  898          }
 771  899  
 772      -        if (!option_spammy && expr->type == EXPR_BINOP && expr->op == '/') {
      900 +        if (expr->type == EXPR_BINOP && expr->op == '/') {
 773  901                  struct range_list *left = NULL;
 774  902                  struct range_list *right = NULL;
 775  903                  struct range_list *abs_right;
 776  904  
 777  905                  /*
 778  906                   * The specific bug I'm dealing with is:
 779  907                   *
 780  908                   * foo = capped_user / unknown;
 781  909                   *
 782  910                   * Instead of just saying foo is now entirely user_rl we should
↓ open down ↓ 49 lines elided ↑ open up ↑
 832  960                  goto found;
 833  961          }
 834  962  
 835  963          return NULL;
 836  964  found:
 837  965          user_data_flag = 1;
 838  966          absolute_rl = var_to_absolute_rl(expr);
 839  967          return clone_rl(rl_intersection(rl, absolute_rl));
 840  968  }
 841  969  
      970 +static bool is_ptr_subtract(struct expression *expr)
      971 +{
      972 +        expr = strip_expr(expr);
      973 +        if (!expr)
      974 +                return false;
      975 +        if (expr->type == EXPR_BINOP && expr->op == '-' &&
      976 +            type_is_ptr(get_type(expr->left))) {
      977 +                return true;
      978 +        }
      979 +        return false;
      980 +}
      981 +
 842  982  int get_user_rl(struct expression *expr, struct range_list **rl)
 843  983  {
      984 +        if (is_ptr_subtract(expr))
      985 +                return 0;
      986 +
 844  987          user_data_flag = 0;
 845  988          no_user_data_flag = 0;
 846  989          custom_get_absolute_rl(expr, &var_user_rl, rl);
 847  990          if (!user_data_flag || no_user_data_flag)
 848  991                  *rl = NULL;
 849  992  
 850  993          return !!*rl;
 851  994  }
 852  995  
 853      -int get_user_rl_spammy(struct expression *expr, struct range_list **rl)
 854      -{
 855      -        int ret;
 856      -
 857      -        option_spammy++;
 858      -        ret = get_user_rl(expr, rl);
 859      -        option_spammy--;
 860      -
 861      -        return ret;
 862      -}
 863      -
 864  996  int is_user_rl(struct expression *expr)
 865  997  {
 866  998          struct range_list *tmp;
 867  999  
 868      -        return get_user_rl_spammy(expr, &tmp);
     1000 +        return !!get_user_rl(expr, &tmp);
 869 1001  }
 870 1002  
 871 1003  int get_user_rl_var_sym(const char *name, struct symbol *sym, struct range_list **rl)
 872 1004  {
 873 1005          struct smatch_state *state;
 874 1006  
 875 1007          state = get_state(my_id, name, sym);
 876 1008          if (state && estate_rl(state)) {
 877 1009                  *rl = estate_rl(state);
 878 1010                  return 1;
 879 1011          }
 880 1012          return 0;
 881 1013  }
 882 1014  
 883      -static void match_call_info(struct expression *expr)
     1015 +static char *get_user_rl_str(struct expression *expr, struct symbol *type)
 884 1016  {
 885 1017          struct range_list *rl;
     1018 +        static char buf[64];
     1019 +
     1020 +        if (!get_user_rl(expr, &rl))
     1021 +                return NULL;
     1022 +        rl = cast_rl(type, rl);
     1023 +        snprintf(buf, sizeof(buf), "%s%s",
     1024 +                 show_rl(rl), user_rl_capped(expr) ? "[c]" : "");
     1025 +        return buf;
     1026 +}
     1027 +
     1028 +static void match_call_info(struct expression *expr)
     1029 +{
 886 1030          struct expression *arg;
 887 1031          struct symbol *type;
 888      -        int i = 0;
     1032 +        char *str;
     1033 +        int i;
 889 1034  
 890 1035          i = -1;
 891 1036          FOR_EACH_PTR(expr->args, arg) {
 892 1037                  i++;
 893 1038                  type = get_arg_type(expr->fn, i);
 894      -
 895      -                if (!get_user_rl(arg, &rl))
     1039 +                str = get_user_rl_str(arg, type);
     1040 +                if (!str)
 896 1041                          continue;
 897 1042  
 898      -                rl = cast_rl(type, rl);
 899      -                sql_insert_caller_info(expr, USER_DATA3, i, "$", show_rl(rl));
     1043 +                sql_insert_caller_info(expr, USER_DATA, i, "$", str);
 900 1044          } END_FOR_EACH_PTR(arg);
 901 1045  }
 902 1046  
 903 1047  static int is_struct_ptr(struct symbol *sym)
 904 1048  {
 905 1049          struct symbol *type;
 906 1050  
 907 1051          if (!sym)
 908 1052                  return 0;
 909 1053          type = get_real_base_type(sym);
↓ open down ↓ 3 lines elided ↑ open up ↑
 913 1057          if (!type || type->type != SYM_STRUCT)
 914 1058                  return 0;
 915 1059          return 1;
 916 1060  }
 917 1061  
 918 1062  static void struct_member_callback(struct expression *call, int param, char *printed_name, struct sm_state *sm)
 919 1063  {
 920 1064          struct smatch_state *state;
 921 1065          struct range_list *rl;
 922 1066          struct symbol *type;
     1067 +        char buf[64];
 923 1068  
 924 1069          /*
 925 1070           * Smatch uses a hack where if we get an unsigned long we say it's
 926 1071           * both user data and it points to user data.  But if we pass it to a
 927 1072           * function which takes an int, then it's just user data.  There's not
 928 1073           * enough bytes for it to be a pointer.
 929 1074           *
 930 1075           */
 931 1076          type = get_arg_type(call->fn, param);
 932 1077          if (type && type_bits(type) < type_bits(&ptr_ctype))
 933 1078                  return;
 934 1079  
 935 1080          if (strcmp(sm->state->name, "") == 0)
 936 1081                  return;
 937 1082  
 938 1083          if (strcmp(printed_name, "*$") == 0 &&
 939 1084              is_struct_ptr(sm->sym))
 940 1085                  return;
 941 1086  
 942      -        state = get_state(SMATCH_EXTRA, sm->name, sm->sym);
     1087 +        state = __get_state(SMATCH_EXTRA, sm->name, sm->sym);
 943 1088          if (!state || !estate_rl(state))
 944 1089                  rl = estate_rl(sm->state);
 945 1090          else
 946 1091                  rl = rl_intersection(estate_rl(sm->state), estate_rl(state));
 947 1092  
 948      -        sql_insert_caller_info(call, USER_DATA3, param, printed_name, show_rl(rl));
     1093 +        if (!rl)
     1094 +                return;
     1095 +
     1096 +        snprintf(buf, sizeof(buf), "%s%s", show_rl(rl),
     1097 +                 estate_capped(sm->state) ? "[c]" : "");
     1098 +        sql_insert_caller_info(call, USER_DATA, param, printed_name, buf);
 949 1099  }
 950 1100  
     1101 +static void db_param_set(struct expression *expr, int param, char *key, char *value)
     1102 +{
     1103 +        struct expression *arg;
     1104 +        char *name;
     1105 +        struct symbol *sym;
     1106 +        struct smatch_state *state;
     1107 +
     1108 +        while (expr->type == EXPR_ASSIGNMENT)
     1109 +                expr = strip_expr(expr->right);
     1110 +        if (expr->type != EXPR_CALL)
     1111 +                return;
     1112 +
     1113 +        arg = get_argument_from_call_expr(expr->args, param);
     1114 +        if (!arg)
     1115 +                return;
     1116 +        name = get_variable_from_key(arg, key, &sym);
     1117 +        if (!name || !sym)
     1118 +                goto free;
     1119 +
     1120 +        state = get_state(my_id, name, sym);
     1121 +        if (!state)
     1122 +                goto free;
     1123 +
     1124 +        set_state(my_id, name, sym, alloc_estate_empty());
     1125 +free:
     1126 +        free_string(name);
     1127 +}
     1128 +
     1129 +static bool param_data_capped(const char *value)
     1130 +{
     1131 +        if (strstr(value, ",c") || strstr(value, "[c"))
     1132 +                return true;
     1133 +        return false;
     1134 +}
     1135 +
 951 1136  static void set_param_user_data(const char *name, struct symbol *sym, char *key, char *value)
 952 1137  {
 953 1138          struct range_list *rl = NULL;
 954 1139          struct smatch_state *state;
     1140 +        struct expression *expr;
 955 1141          struct symbol *type;
 956 1142          char fullname[256];
     1143 +        char *key_orig = key;
     1144 +        bool add_star = false;
 957 1145  
 958      -        if (strcmp(key, "*$") == 0)
 959      -                snprintf(fullname, sizeof(fullname), "*%s", name);
 960      -        else if (strncmp(key, "$", 1) == 0)
 961      -                snprintf(fullname, 256, "%s%s", name, key + 1);
 962      -        else
 963      -                return;
     1146 +        if (strcmp(key, "**$") == 0) {
     1147 +                snprintf(fullname, sizeof(fullname), "**%s", name);
     1148 +        } else {
     1149 +                if (key[0] == '*') {
     1150 +                        add_star = true;
     1151 +                        key++;
     1152 +                }
 964 1153  
 965      -        type = get_member_type_from_key(symbol_expression(sym), key);
     1154 +                snprintf(fullname, 256, "%s%s%s", add_star ? "*" : "", name, key + 1);
     1155 +        }
 966 1156  
 967      -        /* if the caller passes a void pointer with user data */
 968      -        if (strcmp(key, "*$") == 0 && type && type != &void_ctype) {
 969      -                struct expression *expr = symbol_expression(sym);
     1157 +        expr = symbol_expression(sym);
     1158 +        type = get_member_type_from_key(expr, key_orig);
 970 1159  
 971      -                tag_as_user_data(expr);
 972      -                set_points_to_user_data(expr);
 973      -                return;
     1160 +        /*
     1161 +         * Say this function takes a struct ponter but the caller passes
     1162 +         * this_function(skb->data).  We have two options, we could pass *$
     1163 +         * as user data or we could pass foo->bar, foo->baz as user data.
     1164 +         * The second option is easier to implement so we do that.
     1165 +         *
     1166 +         */
     1167 +        if (strcmp(key_orig, "*$") == 0) {
     1168 +                struct symbol *tmp = type;
     1169 +
     1170 +                while (tmp && tmp->type == SYM_PTR)
     1171 +                        tmp = get_real_base_type(tmp);
     1172 +
     1173 +                if (tmp && (tmp->type == SYM_STRUCT || tmp->type == SYM_UNION)) {
     1174 +                        tag_as_user_data(symbol_expression(sym));
     1175 +                        return;
     1176 +                }
 974 1177          }
     1178 +
 975 1179          str_to_rl(type, value, &rl);
 976 1180          state = alloc_estate_rl(rl);
     1181 +        if (param_data_capped(value) || is_capped(expr))
     1182 +                estate_set_capped(state);
 977 1183          set_state(my_id, fullname, sym, state);
 978 1184  }
 979 1185  
 980 1186  static void set_called(const char *name, struct symbol *sym, char *key, char *value)
 981 1187  {
 982 1188          set_state(my_call_id, "this_function", NULL, &called);
 983 1189  }
 984 1190  
 985 1191  static void match_syscall_definition(struct symbol *sym)
 986 1192  {
↓ open down ↓ 18 lines elided ↑ open up ↑
1005 1211                  is_syscall = 1;
1006 1212  
1007 1213          if (!is_syscall)
1008 1214                  return;
1009 1215  
1010 1216          FOR_EACH_PTR(sym->ctype.base_type->arguments, arg) {
1011 1217                  set_state(my_id, arg->ident->name, arg, alloc_estate_whole(get_real_base_type(arg)));
1012 1218          } END_FOR_EACH_PTR(arg);
1013 1219  }
1014 1220  
     1221 +static void store_user_data_return(struct expression *expr, char *key, char *value)
     1222 +{
     1223 +        struct range_list *rl;
     1224 +        struct symbol *type;
     1225 +        char buf[48];
     1226 +
     1227 +        if (strcmp(key, "$") != 0)
     1228 +                return;
     1229 +
     1230 +        type = get_type(expr);
     1231 +        snprintf(buf, sizeof(buf), "return %p", expr);
     1232 +        call_results_to_rl(expr, type, value, &rl);
     1233 +
     1234 +        set_state(my_id, buf, NULL, alloc_estate_rl(rl));
     1235 +}
     1236 +
1015 1237  static void set_to_user_data(struct expression *expr, char *key, char *value)
1016 1238  {
     1239 +        struct smatch_state *state;
1017 1240          char *name;
1018 1241          struct symbol *sym;
1019 1242          struct symbol *type;
1020 1243          struct range_list *rl = NULL;
1021 1244  
1022 1245          type = get_member_type_from_key(expr, key);
1023 1246          name = get_variable_from_key(expr, key, &sym);
1024 1247          if (!name || !sym)
1025 1248                  goto free;
1026 1249  
1027 1250          call_results_to_rl(expr, type, value, &rl);
1028 1251  
1029      -        set_state(my_id, name, sym, alloc_estate_rl(rl));
     1252 +        state = alloc_estate_rl(rl);
     1253 +        if (param_data_capped(value))
     1254 +                estate_set_capped(state);
     1255 +        set_state(my_id, name, sym, state);
1030 1256  free:
1031 1257          free_string(name);
1032      -
1033 1258  }
1034 1259  
1035 1260  static void returns_param_user_data(struct expression *expr, int param, char *key, char *value)
1036 1261  {
1037 1262          struct expression *arg;
1038 1263          struct expression *call;
1039 1264  
1040 1265          call = expr;
1041 1266          while (call->type == EXPR_ASSIGNMENT)
1042 1267                  call = strip_expr(call->right);
1043 1268          if (call->type != EXPR_CALL)
1044 1269                  return;
1045 1270  
1046 1271          if (!we_pass_user_data(call))
1047 1272                  return;
1048 1273  
1049 1274          if (param == -1) {
1050      -                if (expr->type != EXPR_ASSIGNMENT)
     1275 +                if (expr->type != EXPR_ASSIGNMENT) {
     1276 +                        store_user_data_return(expr, key, value);
1051 1277                          return;
     1278 +                }
1052 1279                  set_to_user_data(expr->left, key, value);
1053 1280                  return;
1054 1281          }
1055 1282  
1056 1283          arg = get_argument_from_call_expr(call->args, param);
1057 1284          if (!arg)
1058 1285                  return;
1059 1286          set_to_user_data(arg, key, value);
1060 1287  }
1061 1288  
1062 1289  static void returns_param_user_data_set(struct expression *expr, int param, char *key, char *value)
1063 1290  {
1064 1291          struct expression *arg;
1065 1292  
1066 1293          func_gets_user_data = true;
1067 1294  
1068 1295          if (param == -1) {
1069      -                if (expr->type != EXPR_ASSIGNMENT)
     1296 +                if (expr->type != EXPR_ASSIGNMENT) {
     1297 +                        store_user_data_return(expr, key, value);
1070 1298                          return;
     1299 +                }
1071 1300                  if (strcmp(key, "*$") == 0) {
1072 1301                          set_points_to_user_data(expr->left);
1073 1302                          tag_as_user_data(expr->left);
1074 1303                  } else {
1075 1304                          set_to_user_data(expr->left, key, value);
1076 1305                  }
1077 1306                  return;
1078 1307          }
1079 1308  
1080 1309          while (expr->type == EXPR_ASSIGNMENT)
1081 1310                  expr = strip_expr(expr->right);
1082 1311          if (expr->type != EXPR_CALL)
1083 1312                  return;
1084 1313  
1085 1314          arg = get_argument_from_call_expr(expr->args, param);
1086 1315          if (!arg)
1087 1316                  return;
1088 1317          set_to_user_data(arg, key, value);
1089 1318  }
1090 1319  
1091      -static int has_empty_state(struct sm_state *sm)
1092      -{
1093      -        struct sm_state *tmp;
1094      -
1095      -        FOR_EACH_PTR(sm->possible, tmp) {
1096      -                if (!estate_rl(tmp->state))
1097      -                        return 1;
1098      -        } END_FOR_EACH_PTR(tmp);
1099      -
1100      -        return 0;
1101      -}
1102      -
1103 1320  static void param_set_to_user_data(int return_id, char *return_ranges, struct expression *expr)
1104 1321  {
1105 1322          struct sm_state *sm;
1106 1323          struct smatch_state *start_state;
1107 1324          struct range_list *rl;
1108 1325          int param;
1109 1326          char *return_str;
1110 1327          const char *param_name;
1111 1328          struct symbol *ret_sym;
1112 1329          bool return_found = false;
     1330 +        bool pointed_at_found = false;
     1331 +        char buf[64];
1113 1332  
1114 1333          expr = strip_expr(expr);
1115 1334          return_str = expr_to_str(expr);
1116 1335          ret_sym = expr_to_sym(expr);
1117 1336  
1118 1337          FOR_EACH_MY_SM(my_id, __get_cur_stree(), sm) {
1119      -                if (has_empty_state(sm))
1120      -                        continue;
1121      -
1122 1338                  param = get_param_num_from_sym(sm->sym);
1123 1339                  if (param < 0)
1124 1340                          continue;
1125 1341  
     1342 +                if (!param_was_set_var_sym(sm->name, sm->sym))
     1343 +                        continue;
     1344 +
1126 1345                  /* The logic here was that if we were passed in a user data then
1127 1346                   * we don't record that.  It's like the difference between
1128 1347                   * param_filter and param_set.  When I think about it, I'm not
1129 1348                   * sure it actually works.  It's probably harmless because we
1130 1349                   * checked earlier that we're not returning a parameter...
1131 1350                   * Let's mark this as a TODO.
1132 1351                   */
1133 1352                  start_state = get_state_stree(start_states, my_id, sm->name, sm->sym);
1134 1353                  if (start_state && rl_equiv(estate_rl(sm->state), estate_rl(start_state)))
1135 1354                          continue;
1136 1355  
1137 1356                  param_name = get_param_name(sm);
1138 1357                  if (!param_name)
1139 1358                          continue;
1140 1359                  if (strcmp(param_name, "$") == 0)  /* The -1 param is handled after the loop */
1141 1360                          continue;
1142 1361  
     1362 +                snprintf(buf, sizeof(buf), "%s%s",
     1363 +                         show_rl(estate_rl(sm->state)),
     1364 +                         estate_capped(sm->state) ? "[c]" : "");
1143 1365                  sql_insert_return_states(return_id, return_ranges,
1144      -                                         func_gets_user_data ? USER_DATA3_SET : USER_DATA3,
1145      -                                         param, param_name, show_rl(estate_rl(sm->state)));
     1366 +                                         func_gets_user_data ? USER_DATA_SET : USER_DATA,
     1367 +                                         param, param_name, buf);
1146 1368          } END_FOR_EACH_SM(sm);
1147 1369  
1148      -        if (points_to_user_data(expr)) {
1149      -                sql_insert_return_states(return_id, return_ranges,
1150      -                                         (is_skb_data(expr) || !func_gets_user_data) ?
1151      -                                         USER_DATA3_SET : USER_DATA3,
1152      -                                         -1, "*$", "");
1153      -                goto free_string;
1154      -        }
1155      -
1156      -
     1370 +        /* This if for "return foo;" where "foo->bar" is user data. */
1157 1371          FOR_EACH_MY_SM(my_id, __get_cur_stree(), sm) {
1158 1372                  if (!ret_sym)
1159 1373                          break;
1160 1374                  if (ret_sym != sm->sym)
1161 1375                          continue;
1162 1376  
1163 1377                  param_name = state_name_to_param_name(sm->name, return_str);
1164 1378                  if (!param_name)
1165 1379                          continue;
1166 1380                  if (strcmp(param_name, "$") == 0)
1167 1381                          return_found = true;
     1382 +                if (strcmp(param_name, "*$") == 0)
     1383 +                        pointed_at_found = true;
     1384 +                snprintf(buf, sizeof(buf), "%s%s",
     1385 +                         show_rl(estate_rl(sm->state)),
     1386 +                         estate_capped(sm->state) ? "[c]" : "");
1168 1387                  sql_insert_return_states(return_id, return_ranges,
1169      -                                         func_gets_user_data ? USER_DATA3_SET : USER_DATA3,
1170      -                                         -1, param_name, show_rl(estate_rl(sm->state)));
     1388 +                                         func_gets_user_data ? USER_DATA_SET : USER_DATA,
     1389 +                                         -1, param_name, buf);
1171 1390          } END_FOR_EACH_SM(sm);
1172 1391  
1173      -
     1392 +        /* This if for "return ntohl(foo);" */
1174 1393          if (!return_found && get_user_rl(expr, &rl)) {
     1394 +                snprintf(buf, sizeof(buf), "%s%s",
     1395 +                         show_rl(rl), user_rl_capped(expr) ? "[c]" : "");
1175 1396                  sql_insert_return_states(return_id, return_ranges,
1176      -                                         func_gets_user_data ? USER_DATA3_SET : USER_DATA3,
1177      -                                         -1, "$", show_rl(rl));
1178      -                goto free_string;
     1397 +                                         func_gets_user_data ? USER_DATA_SET : USER_DATA,
     1398 +                                         -1, "$", buf);
1179 1399          }
1180 1400  
1181      -free_string:
     1401 +        /*
     1402 +         * This is to handle things like return skb->data where we don't set a
     1403 +         * state for that.
     1404 +         */
     1405 +        if (!pointed_at_found && points_to_user_data(expr)) {
     1406 +                sql_insert_return_states(return_id, return_ranges,
     1407 +                                         (is_skb_data(expr) || func_gets_user_data) ?
     1408 +                                         USER_DATA_SET : USER_DATA,
     1409 +                                         -1, "*$", "s64min-s64max");
     1410 +        }
     1411 +
1182 1412          free_string(return_str);
1183 1413  }
1184 1414  
     1415 +static void returns_param_capped(struct expression *expr, int param, char *key, char *value)
     1416 +{
     1417 +        struct smatch_state *state, *new;
     1418 +        struct symbol *sym;
     1419 +        char *name;
     1420 +
     1421 +        name = return_state_to_var_sym(expr, param, key, &sym);
     1422 +        if (!name || !sym)
     1423 +                goto free;
     1424 +
     1425 +        state = get_state(my_id, name, sym);
     1426 +        if (!state || estate_capped(state))
     1427 +                goto free;
     1428 +
     1429 +        new = clone_estate(state);
     1430 +        estate_set_capped(new);
     1431 +
     1432 +        set_state(my_id, name, sym, new);
     1433 +free:
     1434 +        free_string(name);
     1435 +}
     1436 +
1185 1437  static struct int_stack *gets_data_stack;
1186 1438  static void match_function_def(struct symbol *sym)
1187 1439  {
1188 1440          func_gets_user_data = false;
1189 1441  }
1190 1442  
1191 1443  static void match_inline_start(struct expression *expr)
1192 1444  {
1193 1445          push_int(&gets_data_stack, func_gets_user_data);
1194 1446  }
1195 1447  
1196 1448  static void match_inline_end(struct expression *expr)
1197 1449  {
1198 1450          func_gets_user_data = pop_int(&gets_data_stack);
1199 1451  }
1200 1452  
1201      -void register_kernel_user_data2(int id)
     1453 +void register_kernel_user_data(int id)
1202 1454  {
1203 1455          int i;
1204 1456  
1205 1457          my_id = id;
1206 1458  
1207 1459          if (option_project != PROJ_KERNEL)
1208 1460                  return;
1209 1461  
     1462 +        set_dynamic_states(my_id);
     1463 +
1210 1464          add_hook(&match_function_def, FUNC_DEF_HOOK);
1211 1465          add_hook(&match_inline_start, INLINE_FN_START);
1212 1466          add_hook(&match_inline_end, INLINE_FN_END);
1213 1467  
1214 1468          add_hook(&save_start_states, AFTER_DEF_HOOK);
1215 1469          add_hook(&free_start_states, AFTER_FUNC_HOOK);
1216 1470          add_hook(&match_save_states, INLINE_FN_START);
1217 1471          add_hook(&match_restore_states, INLINE_FN_END);
1218 1472  
1219 1473          add_unmatched_state_hook(my_id, &empty_state);
↓ open down ↓ 11 lines elided ↑ open up ↑
1231 1485          for (i = 0; i < ARRAY_SIZE(returns_user_data); i++) {
1232 1486                  add_function_assign_hook(returns_user_data[i], &match_user_assign_function, NULL);
1233 1487                  add_function_hook(returns_user_data[i], &match_returns_user_rl, NULL);
1234 1488          }
1235 1489  
1236 1490          add_function_hook("sscanf", &match_sscanf, NULL);
1237 1491  
1238 1492          add_hook(&match_syscall_definition, AFTER_DEF_HOOK);
1239 1493  
1240 1494          add_hook(&match_assign, ASSIGNMENT_HOOK);
     1495 +        select_return_states_hook(PARAM_SET, &db_param_set);
1241 1496          add_hook(&match_condition, CONDITION_HOOK);
1242 1497  
1243 1498          add_hook(&match_call_info, FUNCTION_CALL_HOOK);
1244 1499          add_member_info_callback(my_id, struct_member_callback);
1245      -        select_caller_info_hook(set_param_user_data, USER_DATA3);
1246      -        select_return_states_hook(USER_DATA3, &returns_param_user_data);
1247      -        select_return_states_hook(USER_DATA3_SET, &returns_param_user_data_set);
     1500 +        select_caller_info_hook(set_param_user_data, USER_DATA);
     1501 +        select_return_states_hook(USER_DATA, &returns_param_user_data);
     1502 +        select_return_states_hook(USER_DATA_SET, &returns_param_user_data_set);
     1503 +        select_return_states_hook(CAPPED_DATA, &returns_param_capped);
1248 1504          add_split_return_callback(&param_set_to_user_data);
1249 1505  }
1250 1506  
1251      -void register_kernel_user_data3(int id)
     1507 +void register_kernel_user_data2(int id)
1252 1508  {
1253 1509          my_call_id = id;
1254 1510  
1255 1511          if (option_project != PROJ_KERNEL)
1256 1512                  return;
1257 1513          select_caller_info_hook(set_called, INTERNAL);
1258 1514  }
1259      -
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX