Skip to content
Snippets Groups Projects
Commit 1bc51471 authored by David Bühler's avatar David Bühler
Browse files

[rte] Generates alarms on invalid pointer values.

According to the kernel option -warn-invalid-pointer.
parent 8c94ad72
No related branches found
No related tags found
No related merge requests found
...@@ -1021,6 +1021,7 @@ module RteGen = struct ...@@ -1021,6 +1021,7 @@ module RteGen = struct
let get_pointer_downcast_status = mk_fun "RteGen.get_pointer_downcast_status" let get_pointer_downcast_status = mk_fun "RteGen.get_pointer_downcast_status"
let get_float_to_int_status = mk_fun "RteGen.get_float_to_int_status" let get_float_to_int_status = mk_fun "RteGen.get_float_to_int_status"
let get_finite_float_status = mk_fun "RteGen.get_finite_float_status" let get_finite_float_status = mk_fun "RteGen.get_finite_float_status"
let get_pointer_value_status = mk_fun "RteGen.get_pointer_value_status"
let get_bool_value_status = mk_fun "RteGen.get_bool_value_status" let get_bool_value_status = mk_fun "RteGen.get_bool_value_status"
end end
......
...@@ -903,6 +903,7 @@ module RteGen : sig ...@@ -903,6 +903,7 @@ module RteGen : sig
val get_pointer_downcast_status : (unit -> status_accessor) ref val get_pointer_downcast_status : (unit -> status_accessor) ref
val get_float_to_int_status : (unit -> status_accessor) ref val get_float_to_int_status : (unit -> status_accessor) ref
val get_finite_float_status : (unit -> status_accessor) ref val get_finite_float_status : (unit -> status_accessor) ref
val get_pointer_value_status : (unit -> status_accessor) ref
val get_bool_value_status : (unit -> status_accessor) ref val get_bool_value_status : (unit -> status_accessor) ref
end end
......
...@@ -40,6 +40,7 @@ type t = { ...@@ -40,6 +40,7 @@ type t = {
float_to_int: bool; float_to_int: bool;
finite_float: bool; finite_float: bool;
pointer_call: bool; pointer_call: bool;
pointer_value: bool;
bool_value: bool; bool_value: bool;
} }
...@@ -59,6 +60,7 @@ let all = { ...@@ -59,6 +60,7 @@ let all = {
float_to_int = true; float_to_int = true;
finite_float = true; finite_float = true;
pointer_call = true; pointer_call = true;
pointer_value = true;
bool_value = true; bool_value = true;
} }
...@@ -78,6 +80,7 @@ let none = { ...@@ -78,6 +80,7 @@ let none = {
float_to_int = false; float_to_int = false;
finite_float = false; finite_float = false;
pointer_call = false; pointer_call = false;
pointer_value = false;
bool_value = false; bool_value = false;
} }
...@@ -102,6 +105,7 @@ let default ...@@ -102,6 +105,7 @@ let default
?float_to_int ?float_to_int
?finite_float ?finite_float
?pointer_call ?pointer_call
?pointer_value
?bool_value ?bool_value
() = () =
{ {
...@@ -120,6 +124,7 @@ let default ...@@ -120,6 +124,7 @@ let default
float_to_int = option Options.DoFloatToInt.get float_to_int ; float_to_int = option Options.DoFloatToInt.get float_to_int ;
finite_float = option (fun () -> Kernel.SpecialFloat.get () <> "none") finite_float ; finite_float = option (fun () -> Kernel.SpecialFloat.get () <> "none") finite_float ;
pointer_call = option Options.DoPointerCall.get pointer_call ; pointer_call = option Options.DoPointerCall.get pointer_call ;
pointer_value = option Kernel.InvalidPointer.get pointer_value;
bool_value = option Kernel.InvalidBool.get bool_value ; bool_value = option Kernel.InvalidBool.get bool_value ;
} }
......
...@@ -42,6 +42,7 @@ type t = { ...@@ -42,6 +42,7 @@ type t = {
float_to_int: bool; float_to_int: bool;
finite_float: bool; finite_float: bool;
pointer_call: bool; pointer_call: bool;
pointer_value: bool;
bool_value: bool; bool_value: bool;
} }
...@@ -62,6 +63,7 @@ val default : ...@@ -62,6 +63,7 @@ val default :
?float_to_int:bool -> ?float_to_int:bool ->
?finite_float:bool -> ?finite_float:bool ->
?pointer_call:bool -> ?pointer_call:bool ->
?pointer_value:bool ->
?bool_value:bool -> ?bool_value:bool ->
unit -> t unit -> t
......
...@@ -83,6 +83,14 @@ module Mem_access = ...@@ -83,6 +83,14 @@ module Mem_access =
let additional_parameters = [ Kernel.SafeArrays.parameter ] let additional_parameters = [ Kernel.SafeArrays.parameter ]
end) end)
module Pointer_value =
Make
(struct
let name = "pointer_value"
let parameter = Kernel.InvalidPointer.parameter
let additional_parameters = []
end)
module Pointer_call = module Pointer_call =
Make Make
(struct (struct
......
...@@ -30,6 +30,7 @@ end ...@@ -30,6 +30,7 @@ end
module Initialized: S module Initialized: S
module Mem_access: S module Mem_access: S
module Pointer_value: S
module Pointer_call: S module Pointer_call: S
module Div_mod: S module Div_mod: S
module Shift: S module Shift: S
......
...@@ -96,6 +96,7 @@ let () = ...@@ -96,6 +96,7 @@ let () =
nojournal_register get_pointer_downcast_status Pointer_downcast.accessor; nojournal_register get_pointer_downcast_status Pointer_downcast.accessor;
nojournal_register get_float_to_int_status Float_to_int.accessor; nojournal_register get_float_to_int_status Float_to_int.accessor;
nojournal_register get_finite_float_status Finite_float.accessor; nojournal_register get_finite_float_status Finite_float.accessor;
nojournal_register get_pointer_value_status Pointer_value.accessor;
nojournal_register get_bool_value_status Bool_value.accessor ; nojournal_register get_bool_value_status Bool_value.accessor ;
nojournal_register get_all_status all_statuses; nojournal_register get_all_status all_statuses;
;; ;;
......
...@@ -451,6 +451,24 @@ let finite_float_assertion ~remove_trivial:_ ~on_alarm (fkind, exp) = ...@@ -451,6 +451,24 @@ let finite_float_assertion ~remove_trivial:_ ~on_alarm (fkind, exp) =
let pointer_call ~remove_trivial:_ ~on_alarm (e, args) = let pointer_call ~remove_trivial:_ ~on_alarm (e, args) =
on_alarm ~invalid:false (Alarms.Function_pointer (e, Some args)) on_alarm ~invalid:false (Alarms.Function_pointer (e, Some args))
let is_safe_pointer_value = function
| Lval (Var vi, offset) ->
(* Reading a pointer variable must emit an alarm if an invalid pointer value
could have been written without previous alarm, through:
- an union type, in which case [offset] is not NoOffset;
- an untyped write, in which case the address of [vi] is taken. *)
not vi.vaddrof && offset = NoOffset
| AddrOf (_, NoOffset) | StartOf (_, NoOffset) -> true
| CastE (_typ, e) ->
(* 0 can always be converted into a NULL pointer. *)
let v = get_expr_val e in
Extlib.may_map ~dft:false Integer.(equal zero) v
| _ -> false
let pointer_value ~remove_trivial ~on_alarm expr =
if not (remove_trivial && is_safe_pointer_value expr.enode)
then on_alarm ~invalid:false (Alarms.Invalid_pointer expr)
let bool_value ~remove_trivial ~on_alarm lv = let bool_value ~remove_trivial ~on_alarm lv =
match remove_trivial, lv with match remove_trivial, lv with
| true, (Var vi, NoOffset) | true, (Var vi, NoOffset)
......
...@@ -44,6 +44,7 @@ val downcast_assertion: (typ * exp) alarm_gen ...@@ -44,6 +44,7 @@ val downcast_assertion: (typ * exp) alarm_gen
val float_to_int_assertion: (typ * exp) alarm_gen val float_to_int_assertion: (typ * exp) alarm_gen
val finite_float_assertion: (fkind * exp) alarm_gen val finite_float_assertion: (fkind * exp) alarm_gen
val pointer_call: (exp * exp list) alarm_gen val pointer_call: (exp * exp list) alarm_gen
val pointer_value: exp alarm_gen
val bool_value: lval alarm_gen val bool_value: lval alarm_gen
(* (*
......
...@@ -99,6 +99,9 @@ class annot_visitor kf flags on_alarm = object (self) ...@@ -99,6 +99,9 @@ class annot_visitor kf flags on_alarm = object (self)
method private do_pointer_call () = method private do_pointer_call () =
flags.Flags.pointer_call && not (Generator.Pointer_call.is_computed kf) flags.Flags.pointer_call && not (Generator.Pointer_call.is_computed kf)
method private do_pointer_value () =
flags.Flags.pointer_value && not (Generator.Pointer_value.is_computed kf)
method private do_bool_value () = method private do_bool_value () =
flags.Flags.bool_value && not (Generator.Bool_value.is_computed kf) flags.Flags.bool_value && not (Generator.Bool_value.is_computed kf)
...@@ -275,6 +278,9 @@ class annot_visitor kf flags on_alarm = object (self) ...@@ -275,6 +278,9 @@ class annot_visitor kf flags on_alarm = object (self)
self#generate_assertion Rte.finite_float_assertion (fkind,exp) self#generate_assertion Rte.finite_float_assertion (fkind,exp)
| _ -> ()) | _ -> ())
| BinOp((PlusPI | MinusPI), _, _, _) when self#do_pointer_value () ->
self#generate_assertion Rte.pointer_value exp
| UnOp(Neg, exp, ty) -> | UnOp(Neg, exp, ty) ->
(* Note: if unary minus on unsigned integer is to be understood as (* Note: if unary minus on unsigned integer is to be understood as
"subtracting the promoted value from the largest value "subtracting the promoted value from the largest value
...@@ -290,6 +296,8 @@ class annot_visitor kf flags on_alarm = object (self) ...@@ -290,6 +296,8 @@ class annot_visitor kf flags on_alarm = object (self)
| Lval lval -> | Lval lval ->
(match Cil.(unrollType (typeOfLval lval)) with (match Cil.(unrollType (typeOfLval lval)) with
| TPtr _ when self#do_pointer_value () ->
self#generate_assertion Rte.pointer_value exp
| TInt (IBool,_) when self#do_bool_value () -> | TInt (IBool,_) when self#do_bool_value () ->
self#generate_assertion Rte.bool_value lval self#generate_assertion Rte.bool_value lval
| _ -> ()); | _ -> ());
...@@ -313,6 +321,8 @@ class annot_visitor kf flags on_alarm = object (self) ...@@ -313,6 +321,8 @@ class annot_visitor kf flags on_alarm = object (self)
(* to , from *) (* to , from *)
| TInt _, TPtr _ when self#do_pointer_downcast () -> | TInt _, TPtr _ when self#do_pointer_downcast () ->
self#generate_assertion Rte.downcast_assertion (ty, e) self#generate_assertion Rte.downcast_assertion (ty, e)
| TPtr _, TInt _ when self#do_pointer_value () ->
self#generate_assertion Rte.pointer_value exp
| TInt(kind,_), TInt (_, _) -> | TInt(kind,_), TInt (_, _) ->
let signed = Cil.isSigned kind in let signed = Cil.isSigned kind in
...@@ -339,8 +349,9 @@ class annot_visitor kf flags on_alarm = object (self) ...@@ -339,8 +349,9 @@ class annot_visitor kf flags on_alarm = object (self)
| FP_nan -> | FP_nan ->
self#generate_assertion Rte.finite_float_assertion (fkind,exp) self#generate_assertion Rte.finite_float_assertion (fkind,exp)
end end
| StartOf _ | StartOf _ | AddrOf _ ->
| AddrOf _ if self#do_pointer_value ()
then self#generate_assertion Rte.pointer_value exp
| Info _ | Info _
| UnOp _ | UnOp _
| Const _ | Const _
...@@ -451,6 +462,7 @@ let annotate ?flags kf = ...@@ -451,6 +462,7 @@ let annotate ?flags kf =
let open Flags in let open Flags in
if comp Initialized.accessor flags.initialized ||| if comp Initialized.accessor flags.initialized |||
comp Mem_access.accessor flags.mem_access ||| comp Mem_access.accessor flags.mem_access |||
comp Pointer_value.accessor flags.pointer_value |||
comp Pointer_call.accessor flags.pointer_call ||| comp Pointer_call.accessor flags.pointer_call |||
comp Div_mod.accessor flags.div_mod ||| comp Div_mod.accessor flags.div_mod |||
comp Shift.accessor flags.shift ||| comp Shift.accessor flags.shift |||
......
...@@ -143,6 +143,7 @@ int main(void) ...@@ -143,6 +143,7 @@ int main(void)
[kernel] - shift_value_out_of_bounds = true [kernel] - shift_value_out_of_bounds = true
[kernel] - division_by_zero = true [kernel] - division_by_zero = true
[kernel] - pointer_call = true [kernel] - pointer_call = true
[kernel] - pointer_value = false
[kernel] - mem_access = true [kernel] - mem_access = true
[kernel] - initialized = false [kernel] - initialized = false
[kernel] kf = main [kernel] kf = main
...@@ -159,6 +160,7 @@ int main(void) ...@@ -159,6 +160,7 @@ int main(void)
[kernel] - shift_value_out_of_bounds = true [kernel] - shift_value_out_of_bounds = true
[kernel] - division_by_zero = true [kernel] - division_by_zero = true
[kernel] - pointer_call = true [kernel] - pointer_call = true
[kernel] - pointer_value = false
[kernel] - mem_access = true [kernel] - mem_access = true
[kernel] - initialized = false [kernel] - initialized = false
[kernel] ================================ [kernel] ================================
...@@ -237,6 +239,7 @@ int main(void) ...@@ -237,6 +239,7 @@ int main(void)
[kernel] - shift_value_out_of_bounds = true [kernel] - shift_value_out_of_bounds = true
[kernel] - division_by_zero = true [kernel] - division_by_zero = true
[kernel] - pointer_call = true [kernel] - pointer_call = true
[kernel] - pointer_value = false
[kernel] - mem_access = true [kernel] - mem_access = true
[kernel] - initialized = false [kernel] - initialized = false
[kernel] kf = main [kernel] kf = main
...@@ -253,6 +256,7 @@ int main(void) ...@@ -253,6 +256,7 @@ int main(void)
[kernel] - shift_value_out_of_bounds = true [kernel] - shift_value_out_of_bounds = true
[kernel] - division_by_zero = true [kernel] - division_by_zero = true
[kernel] - pointer_call = true [kernel] - pointer_call = true
[kernel] - pointer_value = false
[kernel] - mem_access = true [kernel] - mem_access = true
[kernel] - initialized = false [kernel] - initialized = false
[kernel] ================================ [kernel] ================================
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment