Print this page
11506 smatch resync


   2  * Copyright (C) 2018 Oracle.
   3  *
   4  * This program is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU General Public License
   6  * as published by the Free Software Foundation; either version 2
   7  * of the License, or (at your option) any later version.
   8  *
   9  * This program is distributed in the hope that it will be useful,
  10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  * GNU General Public License for more details.
  13  *
  14  * You should have received a copy of the GNU General Public License
  15  * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
  16  */
  17 
  18 #include "smatch.h"
  19 #include "smatch_extra.h"
  20 
  21 static int my_id;


  22 
  23 static int suppress_multiple = 1;
  24 
  25 static int is_write(struct expression *expr)
  26 {
  27         return 0;
  28 }
  29 
  30 static int is_read(struct expression *expr)
  31 {
  32         struct expression *parent, *last_parent;
  33         struct statement *stmt;
  34 
  35         if (is_write(expr))
  36                 return 0;
  37 
  38         last_parent = expr;
  39         while ((parent = expr_get_parent_expr(expr))){
  40 
  41                 last_parent = parent;


 148 }
 149 
 150 static void array_check(struct expression *expr)
 151 {
 152         struct expression_list *conditions;
 153         struct expression *array_expr, *offset;
 154         unsigned long long mask;
 155         int array_size;
 156         char *name;
 157 
 158         expr = strip_expr(expr);
 159         if (!is_array(expr))
 160                 return;
 161 
 162         if (is_impossible_path())
 163                 return;
 164         if (is_harmless(expr))
 165                 return;
 166 
 167         array_expr = get_array_base(expr);
 168         if (suppress_multiple && is_ignored_expr(my_id, array_expr))

 169                 return;

 170 
 171         offset = get_array_offset(expr);
 172         if (!is_user_rl(offset))
 173                 return;
 174         if (is_nospec(offset))
 175                 return;
 176 
 177         array_size = get_array_size(array_expr);
 178         if (array_size > 0 && get_max_by_type(offset) < array_size)
 179                 return;
 180 //      binfo = get_bit_info(offset);
 181 //      if (array_size > 0 && binfo && binfo->possible < array_size)
 182 //              return;
 183 
 184         mask = get_mask(offset);
 185         if (mask <= array_size)
 186                 return;
 187 
 188         conditions = get_conditions(offset);
 189 
 190         name = expr_to_str(array_expr);
 191         sm_warning("potential spectre issue '%s' [%s]%s",
 192                name,
 193                is_read(expr) ? "r" : "w",
 194                conditions ? " (local cap)" : "");


 195         if (suppress_multiple)
 196                 add_ignore_expr(my_id, array_expr);
 197         free_string(name);
 198 }
 199 
 200 void check_spectre(int id)
 201 {
 202         my_id = id;
 203 
 204         suppress_multiple = getenv("FULL_SPECTRE") == NULL;
 205 
 206         if (option_project != PROJ_KERNEL)
 207                 return;
 208 
 209         add_hook(&array_check, OP_HOOK);
 210 }


   2  * Copyright (C) 2018 Oracle.
   3  *
   4  * This program is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU General Public License
   6  * as published by the Free Software Foundation; either version 2
   7  * of the License, or (at your option) any later version.
   8  *
   9  * This program is distributed in the hope that it will be useful,
  10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  * GNU General Public License for more details.
  13  *
  14  * You should have received a copy of the GNU General Public License
  15  * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
  16  */
  17 
  18 #include "smatch.h"
  19 #include "smatch_extra.h"
  20 
  21 static int my_id;
  22 extern int second_half_id;
  23 extern void set_spectre_first_half(struct expression *expr);
  24 
  25 static int suppress_multiple = 1;
  26 
  27 static int is_write(struct expression *expr)
  28 {
  29         return 0;
  30 }
  31 
  32 static int is_read(struct expression *expr)
  33 {
  34         struct expression *parent, *last_parent;
  35         struct statement *stmt;
  36 
  37         if (is_write(expr))
  38                 return 0;
  39 
  40         last_parent = expr;
  41         while ((parent = expr_get_parent_expr(expr))){
  42 
  43                 last_parent = parent;


 150 }
 151 
 152 static void array_check(struct expression *expr)
 153 {
 154         struct expression_list *conditions;
 155         struct expression *array_expr, *offset;
 156         unsigned long long mask;
 157         int array_size;
 158         char *name;
 159 
 160         expr = strip_expr(expr);
 161         if (!is_array(expr))
 162                 return;
 163 
 164         if (is_impossible_path())
 165                 return;
 166         if (is_harmless(expr))
 167                 return;
 168 
 169         array_expr = get_array_base(expr);
 170         if (suppress_multiple && is_ignored_expr(my_id, array_expr)) {
 171                 set_spectre_first_half(expr);
 172                 return;
 173         }
 174 
 175         offset = get_array_offset(expr);
 176         if (!is_user_rl(offset))
 177                 return;
 178         if (is_nospec(offset))
 179                 return;
 180 
 181         array_size = get_array_size(array_expr);
 182         if (array_size > 0 && get_max_by_type(offset) < array_size)
 183                 return;
 184 //      binfo = get_bit_info(offset);
 185 //      if (array_size > 0 && binfo && binfo->possible < array_size)
 186 //              return;
 187 
 188         mask = get_mask(offset);
 189         if (mask <= array_size)
 190                 return;
 191 
 192         conditions = get_conditions(offset);
 193 
 194         name = expr_to_str(array_expr);
 195         sm_warning("potential spectre issue '%s' [%s]%s",
 196                name,
 197                is_read(expr) ? "r" : "w",
 198                conditions ? " (local cap)" : "");
 199 
 200         set_spectre_first_half(expr);
 201         if (suppress_multiple)
 202                 add_ignore_expr(my_id, array_expr);
 203         free_string(name);
 204 }
 205 
 206 void check_spectre(int id)
 207 {
 208         my_id = id;
 209 
 210         suppress_multiple = getenv("FULL_SPECTRE") == NULL;
 211 
 212         if (option_project != PROJ_KERNEL)
 213                 return;
 214 
 215         add_hook(&array_check, OP_HOOK);
 216 }