From 0124c32181c27d8e5aa2ee5865f0cbe9f21da519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Thu, 27 Feb 2020 11:24:46 +0100 Subject: [PATCH] [Kernel] New invalid_pointer alarm, for the creation of invalid pointers. --- src/kernel_services/ast_data/alarms.ml | 49 +++++++++++++++++-------- src/kernel_services/ast_data/alarms.mli | 1 + src/plugins/value/alarmset.ml | 5 +++ 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/kernel_services/ast_data/alarms.ml b/src/kernel_services/ast_data/alarms.ml index 2faab4979f1..f251a750c84 100644 --- a/src/kernel_services/ast_data/alarms.ml +++ b/src/kernel_services/ast_data/alarms.ml @@ -41,6 +41,7 @@ type alarm = | Index_out_of_bound of exp (* index *) * exp option (* None = lower bound is zero; Some up = upper bound *) + | Invalid_pointer of exp | Invalid_shift of exp * int option (* strict upper bound, if any *) | Pointer_comparison of exp option (* [None] when implicit comparison to 0 *) @@ -67,7 +68,7 @@ type alarm = (* If you add one constructor to this type, make sure to add a dummy value in the 'reprs' value below, and increase 'nb_alarms' *) -let nb_alarm_constructors = 17 +let nb_alarm_constructors = 18 module D = Datatype.Make_with_collections @@ -82,6 +83,7 @@ module D = [ Division_by_zero e; Memory_access (lv, For_reading); Index_out_of_bound (e, None); + Invalid_pointer e; Invalid_shift (e, None); Pointer_comparison (None, e); Differing_blocks (e, e); @@ -102,20 +104,21 @@ module D = | Division_by_zero _ -> 0 | Memory_access _ -> 1 | Index_out_of_bound _ -> 2 - | Invalid_shift _ -> 3 - | Pointer_comparison _ -> 4 - | Overflow _ -> 5 - | Not_separated _ -> 6 - | Overlap _ -> 7 - | Uninitialized _ -> 8 - | Is_nan_or_infinite _ -> 9 - | Is_nan _ -> 10 - | Float_to_int _ -> 11 - | Differing_blocks _ -> 12 - | Dangling _ -> 13 - | Function_pointer _ -> 14 - | Uninitialized_union _ -> 15 - | Invalid_bool _ -> 16 + | Invalid_pointer _ -> 3 + | Invalid_shift _ -> 4 + | Pointer_comparison _ -> 5 + | Overflow _ -> 6 + | Not_separated _ -> 7 + | Overlap _ -> 8 + | Uninitialized _ -> 9 + | Is_nan_or_infinite _ -> 10 + | Is_nan _ -> 11 + | Float_to_int _ -> 12 + | Differing_blocks _ -> 13 + | Dangling _ -> 14 + | Function_pointer _ -> 15 + | Uninitialized_union _ -> 16 + | Invalid_bool _ -> 17 let () = (* Lightweight checks *) for i = 0 to nb_alarm_constructors - 1 do @@ -136,6 +139,7 @@ module D = | Index_out_of_bound(e11, e12), Index_out_of_bound(e21, e22) -> let n = Exp.compare e11 e21 in if n = 0 then Extlib.opt_compare Exp.compare e12 e22 else n + | Invalid_pointer e1, Invalid_pointer e2 -> Exp.compare e1 e2 | Invalid_shift(e1, n1), Invalid_shift(e2, n2) -> let n = Exp.compare e1 e2 in if n = 0 then Extlib.opt_compare Datatype.Int.compare n1 n2 else n @@ -187,7 +191,8 @@ module D = else Extlib.opt_compare (Extlib.list_compare Exp.compare) l1 l2 | Invalid_bool lv1, Invalid_bool lv2 -> Lval.compare lv1 lv2 | _, (Division_by_zero _ | Memory_access _ | - Index_out_of_bound _ | Invalid_shift _ | Pointer_comparison _ | + Index_out_of_bound _ | Invalid_pointer _ | + Invalid_shift _ | Pointer_comparison _ | Overflow _ | Not_separated _ | Overlap _ | Uninitialized _ | Dangling _ | Is_nan_or_infinite _ | Is_nan _ | Float_to_int _ | Differing_blocks _ | Function_pointer _ | @@ -211,6 +216,7 @@ module D = (nb a, Exp.hash e1, match e2 with None -> 0 | Some e -> 17 + Exp.hash e) + | Invalid_pointer e -> Hashtbl.hash (nb a, Exp.hash e) | Invalid_shift(e, n) -> Hashtbl.hash (nb a, Exp.hash e, n) | Pointer_comparison(e1, e2) -> Hashtbl.hash @@ -255,6 +261,8 @@ module D = (match e2 with None -> ">=" | Some _ -> "<") Printer.pp_exp (match e2 with None -> Cil.zero e1.eloc | Some e -> e) + | Invalid_pointer e -> + Format.fprintf fmt "Invalid_pointer(@[%a@])" Exp.pretty e | Invalid_shift(e, n) -> Format.fprintf fmt "Invalid_shift(@[%a@]@ %s)" Printer.pp_exp e @@ -393,6 +401,7 @@ let get_name = function | Division_by_zero _ -> "division_by_zero" | Memory_access _ -> "mem_access" | Index_out_of_bound _ -> "index_bound" + | Invalid_pointer _ -> "pointer_value" | Invalid_shift _ -> "shift" | Pointer_comparison _ -> "ptr_comparison" | Differing_blocks _ -> "differing_blocks" @@ -416,6 +425,7 @@ let get_description = function | Division_by_zero _ -> "Integer division by zero" | Memory_access _ -> "Invalid pointer dereferencing" | Index_out_of_bound _ -> "Array access out of bounds" + | Invalid_pointer _ -> "Invalid pointer computation" | Invalid_shift _ -> "Invalid shift" | Pointer_comparison _ -> "Invalid pointer comparison" | Differing_blocks _ -> "Operation on pointers within different blocks" @@ -503,6 +513,13 @@ let create_predicate ?(loc=Location.unknown) alarm = let t2 = Logic_utils.expr_to_term ~cast:true e2 in Logic_const.prel ~loc (Rlt, t1, t2)) + | Invalid_pointer e -> + let loc = best_loc ~loc e.eloc in + let t = Logic_utils.expr_to_term ~cast:true e in + if Cil.isFunPtrType (Cil.typeOf e) + then Logic_const.pvalid_function ~loc t + else Logic_const.pobject_pointer ~loc (Logic_const.here_label, t) + | Invalid_shift(e, n) -> (* 0 <= e < n *) let loc = best_loc ~loc e.eloc in diff --git a/src/kernel_services/ast_data/alarms.mli b/src/kernel_services/ast_data/alarms.mli index a369dc60f2b..bdbc4f9fa4d 100644 --- a/src/kernel_services/ast_data/alarms.mli +++ b/src/kernel_services/ast_data/alarms.mli @@ -40,6 +40,7 @@ type alarm = | Index_out_of_bound of exp (** index *) * exp option (** None = lower bound is zero; Some up = upper bound *) + | Invalid_pointer of exp | Invalid_shift of exp * int option (** strict upper bound, if any *) | Pointer_comparison of exp option (** [None] when implicit comparison to NULL pointer *) diff --git a/src/plugins/value/alarmset.ml b/src/plugins/value/alarmset.ml index 1738ac4a35a..222eed3099d 100644 --- a/src/plugins/value/alarmset.ml +++ b/src/plugins/value/alarmset.ml @@ -332,6 +332,9 @@ let emit_alarm kinstr alarm (status:status) = | Alarms.Index_out_of_bound _ -> register_alarm "accessing out of bounds index" + | Alarms.Invalid_pointer _ -> + register_alarm "invalid pointer creation" + | Alarms.Differing_blocks _ -> register_alarm "pointer subtraction" @@ -367,6 +370,7 @@ let emit_alarm kinstr alarm (status:status) = let height_alarm = let open Value_util in function | Alarms.Division_by_zero e | Alarms.Index_out_of_bound (e,_) + | Alarms.Invalid_pointer e | Alarms.Invalid_shift (e,_) | Alarms.Overflow (_,e,_,_) | Alarms.Float_to_int (e,_,_) @@ -426,6 +430,7 @@ let warn_alarm warn_mode = function | Alarms.Invalid_shift _ | Alarms.Memory_access _ | Alarms.Index_out_of_bound _ + | Alarms.Invalid_pointer _ | Alarms.Is_nan_or_infinite _ | Alarms.Is_nan _ | Alarms.Not_separated _ -- GitLab