Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor and fix race access distribution #1084

Merged
merged 54 commits into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
4e884c6
Remove unnecessary type definitions
karoliineh Jun 6, 2023
2d7d09c
Replace failwith with exception and catch that instead
karoliineh Jun 6, 2023
96f67f5
Refactor pattern matching
karoliineh Jun 6, 2023
8270028
Refactor: remove typeSig function calls
karoliineh Jun 6, 2023
e07ee47
Add type race cram tests
karoliineh Jun 6, 2023
41c2b11
Remove unused function parameters from access
karoliineh Jun 6, 2023
96c26ff
Refactor offset option type in access
karoliineh Jun 6, 2023
913a2a7
Refactor pattern matching in add in access
karoliineh Jun 6, 2023
c75de0f
Refactor compinfo in add_propagate in access
karoliineh Jun 6, 2023
f4a692e
Add unsound race test with array and struct
karoliineh Jun 6, 2023
467a2e3
Merge branch 'master' into access-analysis-propagate
sim642 Jun 7, 2023
e07933e
Refactor Access memory location type to avoid offset redundancy
sim642 Jun 7, 2023
4e16e1f
Move Access.Memo up to add_one
sim642 Jun 7, 2023
64d69c3
Simplify Access.add_struct
sim642 Jun 7, 2023
5d11f6f
Add Access.Memo.type_of
sim642 Jun 7, 2023
5fd977f
Fix Access.add_struct struct case matching
sim642 Jun 7, 2023
23ed02d
Add test case for typedef
karoliineh Jun 7, 2023
74a036f
Disable races from free in chrony-name2ipaddress
sim642 Jun 7, 2023
36c91c5
Move Access.Memo up to add_struct
sim642 Jun 7, 2023
035b7e3
Revert "Refactor: remove typeSig function calls"
karoliineh Jun 7, 2023
8ac30e9
Replace general Hashtbl with a specialized table with CilType.Typsig …
karoliineh Jun 7, 2023
717778a
Move Access.Memo up to add_propagate
sim642 Jun 7, 2023
219825b
Merge remote-tracking branch 'upstream/access-analysis-propagate' int…
sim642 Jun 7, 2023
2ca99f3
Remove now-unused Access.type_from_type_offset
sim642 Jun 7, 2023
9728852
Make `Var case more direct in Access
sim642 Jun 8, 2023
f38c4d6
Make Access fallback type lazy
sim642 Jun 8, 2023
2aa2837
Add TODOs to Access.get_type
sim642 Jun 8, 2023
491d01c
Add Access ignorable type TODOs
sim642 Jun 8, 2023
0fd1c3f
Add Access tracing
sim642 Jun 8, 2023
bbf4df0
Remove unused code from Access
sim642 Jun 9, 2023
7c8928f
Add second Access typedef test
sim642 Jun 9, 2023
ab4db5c
Add failing type nested fields race test
sim642 Jun 9, 2023
104615b
Add failing type array fields no race test
sim642 Jun 9, 2023
9fced76
Add failing deeper type nested fields race tests
sim642 Jun 9, 2023
4b53fc8
Reimplement Access.add_propagate to be more sound and more precise
sim642 Jun 9, 2023
ba7e4d6
Fix 06-symbeq/50-type_array_via_ptr_rc
sim642 Jun 9, 2023
1472eda
Remove old Access.add_propagate
sim642 Jun 9, 2023
d431178
Clean up new Access.add_propagate
sim642 Jun 9, 2023
3b7466a
Refactor Access.add cases
sim642 Jun 9, 2023
233e8bf
Add more ignorable Access types
sim642 Jun 12, 2023
61ceddb
Disable nonstatic on Goblint stubs
sim642 Jun 12, 2023
b18c2af
Add TODO about unsound type in Access
sim642 Jun 12, 2023
e079c00
Document Access distribution logic
sim642 Jun 12, 2023
38a4a49
Add two disjoint_types tests
sim642 Jun 13, 2023
47de6f4
Fix and simplify Access.add for arithmethic types
sim642 Jun 13, 2023
4c6ae91
Fix and simplify Access.add_distribute_inner
sim642 Jun 13, 2023
24a559d
Remove Access.Type_offset_error
sim642 Jun 13, 2023
a1c87c6
Rename and flip option ana.mutex.disjoint_types -> ana.race.direct-ar…
sim642 Jun 13, 2023
db42e88
Extract Access.nested_offsets
sim642 Jun 13, 2023
36e47f6
Implement nicer anonstruct and anonunion matching in Access.is_ignora…
sim642 Jun 13, 2023
d13acea
Remove system-dependent parts of cram tests
sim642 Jun 14, 2023
4bdc294
Disable info messages in type-based access cram tests
sim642 Jun 14, 2023
eb0e1c7
Try to make cram test output deterministic
sim642 Jun 15, 2023
6ac8db2
Simplify access code
sim642 Jun 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/analyses/accessAnalysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,15 @@ struct
+ [deref=true], [reach=false] - Access [exp] by dereferencing once (may-point-to), used for lval writes and shallow special accesses.
+ [deref=true], [reach=true] - Access [exp] by dereferencing transitively (reachable), used for deep special accesses. *)
let access_one_top ?(force=false) ?(deref=false) ctx (kind: AccessKind.t) reach exp =
if M.tracing then M.traceli "access" "access_one_top %a %b %a:\n" AccessKind.pretty kind reach d_exp exp;
if M.tracing then M.traceli "access" "access_one_top %a (kind = %a, reach = %B, deref = %B)\n" CilType.Exp.pretty exp AccessKind.pretty kind reach deref;
if force || !collect_local || !emit_single_threaded || ThreadFlag.has_ever_been_multi (Analyses.ask_of_ctx ctx) then (
if deref then
do_access ctx kind reach exp;
Access.distribute_access_exp (do_access ctx Read false) exp
if M.tracing then M.tracei "access" "distribute_access_exp\n";
Access.distribute_access_exp (do_access ctx Read false) exp;
if M.tracing then M.traceu "access" "distribute_access_exp\n";
michael-schwarz marked this conversation as resolved.
Show resolved Hide resolved
);
if M.tracing then M.traceu "access" "access_one_top %a %b %a\n" AccessKind.pretty kind reach d_exp exp
if M.tracing then M.traceu "access" "access_one_top\n"

(** We just lift start state, global and dependency functions: *)
let startstate v = ()
Expand Down
59 changes: 26 additions & 33 deletions src/analyses/raceAnalysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,26 @@ struct
1. (lval, type) -> accesses -- used for warnings
2. varinfo -> set of (lval, type) -- used for IterSysVars Global *)

module V0 = Printable.Prod (Access.LVOpt) (Access.T)
module V =
struct
include Printable.Either (V0) (CilType.Varinfo)
include Printable.Either (Access.Memo) (CilType.Varinfo)
let name () = "race"
let access x = `Left x
let vars x = `Right x
let is_write_only _ = true
end

module V0Set = SetDomain.Make (V0)
module MemoSet = SetDomain.Make (Access.Memo)
module G =
struct
include Lattice.Lift2 (Access.AS) (V0Set) (Printable.DefaultNames)
include Lattice.Lift2 (Access.AS) (MemoSet) (Printable.DefaultNames)

let access = function
| `Bot -> Access.AS.bot ()
| `Lifted1 x -> x
| _ -> failwith "Race.access"
let vars = function
| `Bot -> V0Set.bot ()
| `Bot -> MemoSet.bot ()
| `Lifted2 x -> x
| _ -> failwith "Race.vars"
let create_access access = `Lifted1 access
Expand All @@ -51,41 +50,34 @@ struct
vulnerable := 0;
unsafe := 0

let side_vars ctx lv_opt ty =
match lv_opt with
| Some (v, _) ->
let side_vars ctx memo =
match memo with
| (`Var v, _) ->
if !AnalysisState.should_warn then
ctx.sideg (V.vars v) (G.create_vars (V0Set.singleton (lv_opt, ty)))
| None ->
ctx.sideg (V.vars v) (G.create_vars (MemoSet.singleton memo))
| _ ->
()

let side_access ctx ty lv_opt (conf, w, loc, e, a) =
let ty =
if Option.is_some lv_opt then
`Type Cil.voidType (* avoid unsound type split for alloc variables *)
else
ty
in
let side_access ctx (conf, w, loc, e, a) memo =
if !AnalysisState.should_warn then
ctx.sideg (V.access (lv_opt, ty)) (G.create_access (Access.AS.singleton (conf, w, loc, e, a)));
side_vars ctx lv_opt ty
ctx.sideg (V.access memo) (G.create_access (Access.AS.singleton (conf, w, loc, e, a)));
side_vars ctx memo

let query ctx (type a) (q: a Queries.t): a Queries.result =
match q with
| WarnGlobal g ->
let g: V.t = Obj.obj g in
begin match g with
| `Left g' -> (* accesses *)
| `Left memo -> (* accesses *)
(* ignore (Pretty.printf "WarnGlobal %a\n" CilType.Varinfo.pretty g); *)
let accs = G.access (ctx.global g) in
let (lv, ty) = g' in
let mem_loc_str = GobPretty.sprint Access.d_memo (ty, lv) in
Timing.wrap ~args:[("memory location", `String mem_loc_str)] "race" (Access.warn_global safe vulnerable unsafe g') accs
let mem_loc_str = GobPretty.sprint Access.Memo.pretty memo in
Timing.wrap ~args:[("memory location", `String mem_loc_str)] "race" (Access.warn_global safe vulnerable unsafe memo) accs
| `Right _ -> (* vars *)
()
end
| IterSysVars (Global g, vf) ->
V0Set.iter (fun v ->
MemoSet.iter (fun v ->
vf (Obj.repr (V.access v))
) (G.vars (ctx.global (V.vars g)))
| _ -> Queries.Result.top q
Expand All @@ -96,17 +88,18 @@ struct
(* must use original (pre-assign, etc) ctx queries *)
let conf = 110 in
let module LS = Queries.LS in
let part_access (vo:varinfo option) (oo: offset option): MCPAccess.A.t =
let part_access (vo:varinfo option): MCPAccess.A.t =
(*partitions & locks*)
Obj.obj (octx.ask (PartAccess (Memory {exp=e; var_opt=vo; kind})))
in
let add_access conf vo oo =
let a = part_access vo oo in
Access.add (side_access octx) e kind conf vo oo a;
let loc = Option.get !Node.current_node in
let add_access conf voffs =
let a = part_access (Option.map fst voffs) in
Access.add (side_access octx (conf, kind, loc, e, a)) e voffs;
in
let add_access_struct conf ci =
let a = part_access None None in
Access.add_struct (side_access octx) e kind conf (`Struct (ci,`NoOffset)) None a
let a = part_access None in
Access.add_distribute_inner (side_access octx (conf, kind, loc, e, a)) (`Type (TComp (ci, [])), `NoOffset)
in
let has_escaped g = octx.ask (Queries.MayEscape g) in
(* The following function adds accesses to the lval-set ls
Expand All @@ -118,9 +111,9 @@ struct
let f (var, offs) =
let coffs = Offset.Exp.to_cil offs in
if CilType.Varinfo.equal var dummyFunDec.svar then
add_access conf None (Some coffs)
add_access conf None
else
add_access conf (Some var) (Some coffs)
add_access conf (Some (var, coffs))
in
LS.iter f ls
in
Expand All @@ -147,7 +140,7 @@ struct
end;
on_lvals ls !includes_uk
| _ ->
add_access (conf - 60) None None
add_access (conf - 60) None
end;
ctx.local
| _ ->
Expand Down
3 changes: 2 additions & 1 deletion src/cdomains/offset.ml
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ struct
let s = GobPretty.sprintf "Addr.type_offset: field %s not found in type %a" f.fname d_plaintype t in
raise (Type_of_error (t, s))
in type_of ~base:fi.ftype o
| TComp _, `Index (_,o) -> type_of ~base:t o (* this happens (hmmer, perlbench). safe? *)
(* TODO: Why? Imprecise on zstd-thread-pool regression tests. *)
(* | TComp _, `Index (_,o) -> type_of ~base:t o (* this happens (hmmer, perlbench). safe? *) *)
| t,o ->
let s = GobPretty.sprintf "Addr.type_offset: could not follow offset in type. type: %a, offset: %a" d_plaintype t pretty o in
raise (Type_of_error (t, s))
Expand Down
Loading