Print this page
11506 smatch resync

Split Close
Expand all
Collapse all
          --- old/usr/src/tools/smatch/src/check_string_len.c
          +++ new/usr/src/tools/smatch/src/check_string_len.c
↓ open down ↓ 27 lines elided ↑ open up ↑
  28   28  
  29   29  static int my_id;
  30   30  
  31   31  struct param_info {
  32   32          int buf_or_limit;
  33   33          int string;
  34   34  };
  35   35  
  36   36  struct param_info zero_one = {0, 1};
  37   37  
  38      -static int handle_format(struct expression *call, char **pp, int *arg_nr)
       38 +static int handle_format(struct expression *call, char **pp, int *arg_nr, bool use_max)
  39   39  {
  40   40          struct expression *arg;
  41   41          char *p = *pp;
  42   42          int ret = 1;
  43   43          char buf[256];
  44      -        sval_t max;
       44 +        sval_t sval;
  45   45  
  46   46          p++;  /* we passed it with *p == '%' */
  47   47  
  48   48          if (*p == '%') {
  49   49                  p++;
  50   50                  ret = 1;
  51   51                  goto out_no_arg;
  52   52          }
  53   53          if (*p == 'c') {
  54   54                  p++;
↓ open down ↓ 79 lines elided ↑ open up ↑
 134  134                  p++;
 135  135                  goto out;
 136  136          }
 137  137  
 138  138          if (*p != 'd' && *p != 'i' && *p != 'x' && *p != 'X' && *p != 'u' && *p != 'p') {
 139  139                  ret = 1;
 140  140                  p++;
 141  141                  goto out;
 142  142          }
 143  143  
 144      -        get_absolute_max(arg, &max);
      144 +        if (use_max) {
      145 +                get_absolute_max(arg, &sval);
      146 +        } else {
      147 +                get_absolute_min(arg, &sval);
      148 +                if (sval_is_negative(sval))
      149 +                        sval.value = 0;
      150 +        }
 145  151  
      152 +
 146  153          if (*p == 'x' || *p == 'X' || *p == 'p') {
 147      -                ret = snprintf(buf, sizeof(buf), "%llx", max.uvalue);
      154 +                ret = snprintf(buf, sizeof(buf), "%llx", sval.uvalue);
 148  155          } else if (*p == 'u') {
 149      -                ret = snprintf(buf, sizeof(buf), "%llu", max.uvalue);
      156 +                ret = snprintf(buf, sizeof(buf), "%llu", sval.uvalue);
 150  157          } else if (!expr_unsigned(arg)) {
 151  158                  sval_t min;
 152  159                  int tmp;
 153  160  
 154      -                ret = snprintf(buf, sizeof(buf), "%lld", max.value);
      161 +                ret = snprintf(buf, sizeof(buf), "%lld", sval.value);
 155  162                  get_absolute_min(arg, &min);
 156  163                  tmp = snprintf(buf, sizeof(buf), "%lld", min.value);
 157  164                  if (tmp > ret)
 158  165                          ret = tmp;
 159  166          } else {
 160      -                ret = snprintf(buf, sizeof(buf), "%lld", max.value);
      167 +                ret = snprintf(buf, sizeof(buf), "%lld", sval.value);
 161  168          }
 162  169          p++;
 163  170  
 164  171  out:
 165  172          (*arg_nr)++;
 166  173  out_no_arg:
 167  174          *pp = p;
 168  175          return ret;
 169  176  }
 170  177  
 171      -int get_formatted_string_size(struct expression *call, int arg)
      178 +int get_formatted_string_size_helper(struct expression *call, int arg, bool use_max)
 172  179  {
 173  180          struct expression *expr;
 174  181          char *p;
 175  182          int count;
 176  183  
 177  184          expr = get_argument_from_call_expr(call->args, arg);
 178  185          if (!expr || expr->type != EXPR_STRING)
 179  186                  return -1;
 180  187  
 181  188          arg++;
 182  189          count = 0;
 183  190          p = expr->string->data;
 184  191          while (*p) {
 185  192  
 186  193                  if (*p == '%') {
 187      -                        count += handle_format(call, &p, &arg);
      194 +                        count += handle_format(call, &p, &arg, use_max);
 188  195                  } else if (*p == '\\') {
 189  196                          p++;
 190  197                  }else {
 191  198                          p++;
 192  199                          count++;
 193  200                  }
 194  201          }
 195  202  
 196      -        count++; /* count the NUL terminator */
 197  203          return count;
 198  204  }
 199  205  
      206 +int get_formatted_string_size(struct expression *call, int arg)
      207 +{
      208 +        return get_formatted_string_size_helper(call, arg, true);
      209 +}
      210 +
      211 +int get_formatted_string_min_size(struct expression *call, int arg)
      212 +{
      213 +        return get_formatted_string_size_helper(call, arg, false);
      214 +}
      215 +
 200  216  static void match_not_limited(const char *fn, struct expression *call, void *info)
 201  217  {
 202  218          struct param_info *params = info;
 203  219          struct range_list *rl;
 204  220          struct expression *dest;
 205  221          struct expression *arg;
 206  222          int buf_size, size;
 207  223          int user = 0;
 208  224          int i;
 209  225          int offset = 0;
↓ open down ↓ 7 lines elided ↑ open up ↑
 217  233                          offset = max.value;
 218  234                  dest = dest->left;
 219  235          }
 220  236  
 221  237  
 222  238          buf_size = get_array_size_bytes(dest);
 223  239          if (buf_size <= 0)
 224  240                  return;
 225  241  
 226  242          size = get_formatted_string_size(call, params->string);
 227      -        if (size <= 0)
      243 +        if (size < 0)
 228  244                  return;
 229  245          if (size < offset)
 230  246                  size -= offset;
      247 +        size++; /* add the NULL terminator */
 231  248          if (size <= buf_size)
 232  249                  return;
 233  250  
 234  251          i = 0;
 235  252          FOR_EACH_PTR(call->args, arg) {
 236  253                  if (i++ <= params->string)
 237  254                          continue;
 238  255                  if (get_user_rl(arg, &rl))
 239  256                          user = 1;
 240  257          } END_FOR_EACH_PTR(arg);
↓ open down ↓ 11 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX