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

Spawn threads created from unknown functions as non-unique #1187

Merged
merged 7 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions src/analyses/abortUnless.ml
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ struct
false

let startstate v = false
let threadenter ctx lval f args = [false]
let threadspawn ctx lval f args fctx = false
let threadenter ctx ~multiple lval f args = [false]
let threadspawn ctx ~multiple lval f args fctx = false
let exitstate v = false
end

Expand Down
4 changes: 2 additions & 2 deletions src/analyses/accessAnalysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ struct

(** We just lift start state, global and dependency functions: *)
let startstate v = ()
let threadenter ctx lval f args = [()]
let threadenter ctx ~multiple lval f args = [()]
let exitstate v = ()
let context fd d = ()

Expand Down Expand Up @@ -121,7 +121,7 @@ struct
ctx.local


let threadspawn ctx lval f args fctx =
let threadspawn ctx ~multiple lval f args fctx =
(* must explicitly access thread ID lval because special to pthread_create doesn't if singlethreaded before *)
begin match lval with
| None -> ()
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/activeLongjmp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ struct

(* Initial values don't really matter: overwritten at longjmp call. *)
let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]
let threadenter ctx ~multiple lval f args = [D.bot ()]
let exitstate v = D.top ()

let query ctx (type a) (q: a Queries.t): a Queries.result =
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/activeSetjmp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct
| _ -> ctx.local

let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]
let threadenter ctx ~multiple lval f args = [D.bot ()]
let exitstate v = D.top ()

let query ctx (type a) (q: a Queries.t): a Queries.result =
Expand Down
4 changes: 2 additions & 2 deletions src/analyses/apron/relationAnalysis.apron.ml
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ struct

(* Thread transfer functions. *)

let threadenter ctx lval f args =
let threadenter ctx ~multiple lval f args =
let st = ctx.local in
match Cilfacade.find_varinfo_fundec f with
| fd ->
Expand All @@ -665,7 +665,7 @@ struct
(* TODO: do something like base? *)
failwith "relation.threadenter: unknown function"

let threadspawn ctx lval f args fctx =
let threadspawn ctx ~multiple lval f args fctx =
ctx.local

let event ctx e octx =
Expand Down
18 changes: 9 additions & 9 deletions src/analyses/base.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1944,7 +1944,7 @@ struct



let forkfun (ctx:(D.t, G.t, C.t, V.t) Analyses.ctx) (lv: lval option) (f: varinfo) (args: exp list) : (lval option * varinfo * exp list) list =
let forkfun (ctx:(D.t, G.t, C.t, V.t) Analyses.ctx) (lv: lval option) (f: varinfo) (args: exp list) : (lval option * varinfo * exp list) list * bool =
let create_thread lval arg v =
try
(* try to get function declaration *)
Expand Down Expand Up @@ -1985,7 +1985,7 @@ struct
else
start_funvars
in
List.filter_map (create_thread (Some (Mem id, NoOffset)) (Some ptc_arg)) start_funvars_with_unknown
List.filter_map (create_thread (Some (Mem id, NoOffset)) (Some ptc_arg)) start_funvars_with_unknown, false
end
| _, _ when get_bool "sem.unknown_function.spawn" ->
(* TODO: Remove sem.unknown_function.spawn check because it is (and should be) really done in LibraryFunctions.
Expand All @@ -1998,9 +1998,9 @@ struct
let deep_flist = collect_invalidate ~deep:true (Analyses.ask_of_ctx ctx) ctx.global ctx.local deep_args in
let flist = shallow_flist @ deep_flist in
let addrs = List.concat_map AD.to_var_may flist in
if addrs <> [] then M.debug ~category:Analyzer "Spawning functions from unknown function: %a" (d_list ", " CilType.Varinfo.pretty) addrs;
List.filter_map (create_thread None None) addrs
| _, _ -> []
if addrs <> [] then M.debug ~category:Analyzer "Spawning non-unique functions from unknown function: %a" (d_list ", " CilType.Varinfo.pretty) addrs;
List.filter_map (create_thread None None) addrs, true
| _, _ -> [], false

let assert_fn ctx e refine =
(* make the state meet the assertion in the rest of the code *)
Expand Down Expand Up @@ -2131,9 +2131,9 @@ struct
let addr = eval_lv (Analyses.ask_of_ctx ctx) ctx.global ctx.local lval in
(addr, AD.type_of addr)
in
let forks = forkfun ctx lv f args in
let forks, multiple = forkfun ctx lv f args in
if M.tracing then if not (List.is_empty forks) then M.tracel "spawn" "Base.special %s: spawning functions %a\n" f.vname (d_list "," CilType.Varinfo.pretty) (List.map BatTuple.Tuple3.second forks);
List.iter (BatTuple.Tuple3.uncurry ctx.spawn) forks;
List.iter (BatTuple.Tuple3.uncurry (ctx.spawn ~multiple)) forks;
let st: store = ctx.local in
let gs = ctx.global in
let desc = LF.find f in
Expand Down Expand Up @@ -2641,7 +2641,7 @@ struct
in
combine_one ctx.local after

let threadenter ctx (lval: lval option) (f: varinfo) (args: exp list): D.t list =
let threadenter ctx ~multiple (lval: lval option) (f: varinfo) (args: exp list): D.t list =
match Cilfacade.find_varinfo_fundec f with
| fd ->
[make_entry ~thread:true ctx fd args]
Expand All @@ -2651,7 +2651,7 @@ struct
let st = special_unknown_invalidate ctx (Analyses.ask_of_ctx ctx) ctx.global st f args in
[st]

let threadspawn ctx (lval: lval option) (f: varinfo) (args: exp list) fctx: D.t =
let threadspawn ctx ~multiple (lval: lval option) (f: varinfo) (args: exp list) fctx: D.t =
begin match lval with
| Some lval ->
begin match ThreadId.get_current (Analyses.ask_of_ctx fctx) with
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/basePriv.ml
Original file line number Diff line number Diff line change
Expand Up @@ -893,7 +893,7 @@ end
module MinePrivBase =
struct
include NoFinalize
include ConfCheck.RequireMutexPathSensInit
include ConfCheck.RequireMutexPathSensOneMainInit
include MutexGlobals (* explicit not needed here because G is Prod anyway? *)

let thread_join ?(force=false) ask get e st = st
Expand Down
4 changes: 3 additions & 1 deletion src/analyses/commonPriv.ml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ struct
if not mutex_active then failwith "Privatization (to be useful) requires the 'mutex' analysis to be enabled (it is currently disabled)"
end

module RequireMutexPathSensInit =
module RequireMutexPathSensOneMainInit =
struct
let init () =
RequireMutexActivatedInit.init ();
let mutex_path_sens = List.mem "mutex" (GobConfig.get_string_list "ana.path_sens") in
if not mutex_path_sens then failwith "The activated privatization requires the 'mutex' analysis to be enabled & path sensitive (it is currently enabled, but not path sensitive)";
let mainfuns = List.length @@ GobConfig.get_list "mainfun" in
if not (mainfuns = 1) then failwith "The activated privatization requires exactly one main function to be specified";
()
end

Expand Down
4 changes: 2 additions & 2 deletions src/analyses/condVars.ml
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@ struct
ctx.local

let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]
let threadspawn ctx lval f args fctx = ctx.local
let threadenter ctx ~multiple lval f args = [D.bot ()]
let threadspawn ctx ~multiple lval f args fctx = ctx.local
let exitstate v = D.bot ()
end

Expand Down
4 changes: 2 additions & 2 deletions src/analyses/expsplit.ml
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ struct
in
emit_splits ctx d

let threadenter ctx lval f args = [ctx.local]
let threadenter ctx ~multiple lval f args = [ctx.local]

let threadspawn ctx lval f args fctx =
let threadspawn ctx ~multiple lval f args fctx =
emit_splits_ctx ctx

let event ctx (event: Events.t) octx =
Expand Down
4 changes: 2 additions & 2 deletions src/analyses/extractPthread.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1238,7 +1238,7 @@ module Spec : Analyses.MCPSpec = struct
(Ctx.top ())


let threadenter ctx lval f args =
let threadenter ctx ~multiple lval f args =
let d : D.t = ctx.local in
let tasks = ctx.global tasks_var in
(* TODO: optimize finding *)
Expand All @@ -1254,7 +1254,7 @@ module Spec : Analyses.MCPSpec = struct
[ { f_d with pred = d.pred } ]


let threadspawn ctx lval f args fctx = ctx.local
let threadspawn ctx ~multiple lval f args fctx = ctx.local

let exitstate v = D.top ()

Expand Down
4 changes: 2 additions & 2 deletions src/analyses/fileUse.ml
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,8 @@ struct
| _ -> m

let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]
let threadspawn ctx lval f args fctx = ctx.local
let threadenter ctx ~multiple lval f args = [D.bot ()]
let threadspawn ctx ~multiple lval f args fctx = ctx.local
let exitstate v = D.bot ()
end

Expand Down
2 changes: 1 addition & 1 deletion src/analyses/locksetAnalysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct
module C = D

let startstate v = D.empty ()
let threadenter ctx lval f args = [D.empty ()]
let threadenter ctx ~multiple lval f args = [D.empty ()]
let exitstate v = D.empty ()
end

Expand Down
16 changes: 8 additions & 8 deletions src/analyses/mCP.ml
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,9 @@ struct
f ((k,v::a')::a) b
in f [] xs

let do_spawns ctx (xs:(varinfo * (lval option * exp list)) list) =
let do_spawns ctx (xs:(varinfo * (lval option * exp list * bool)) list) =
let spawn_one v d =
List.iter (fun (lval, args) -> ctx.spawn lval v args) d
List.iter (fun (lval, args, multiple) -> ctx.spawn ~multiple lval v args) d
in
if get_bool "exp.single-threaded" then
M.msg_final Error ~category:Unsound "Thread not spawned"
Expand Down Expand Up @@ -324,8 +324,8 @@ struct

and outer_ctx tfname ?spawns ?sides ?emits ctx =
let spawn = match spawns with
| Some spawns -> (fun l v a -> spawns := (v,(l,a)) :: !spawns)
| None -> (fun v d -> failwith ("Cannot \"spawn\" in " ^ tfname ^ " context."))
| Some spawns -> (fun ?(multiple=false) l v a -> spawns := (v,(l,a,multiple)) :: !spawns)
| None -> (fun ?(multiple=false) v d -> failwith ("Cannot \"spawn\" in " ^ tfname ^ " context."))
in
let sideg = match sides with
| Some sides -> (fun v g -> sides := (v, (!WideningTokens.side_tokens, g)) :: !sides)
Expand Down Expand Up @@ -567,28 +567,28 @@ struct
let d = do_emits ctx !emits d q in
if q then raise Deadcode else d

let threadenter (ctx:(D.t, G.t, C.t, V.t) ctx) lval f a =
let threadenter (ctx:(D.t, G.t, C.t, V.t) ctx) ~multiple lval f a =
let sides = ref [] in
let emits = ref [] in
let ctx'' = outer_ctx "threadenter" ~sides ~emits ctx in
let f (n,(module S:MCPSpec),d) =
let ctx' : (S.D.t, S.G.t, S.C.t, S.V.t) ctx = inner_ctx "threadenter" ctx'' n d in
map (fun d -> (n, repr d)) @@ S.threadenter ctx' lval f a
map (fun d -> (n, repr d)) @@ (S.threadenter ~multiple) ctx' lval f a
in
let css = map f @@ spec_list ctx.local in
do_sideg ctx !sides;
(* TODO: this do_emits is now different from everything else *)
map (fun d -> do_emits ctx !emits d false) @@ map topo_sort_an @@ n_cartesian_product css

let threadspawn (ctx:(D.t, G.t, C.t, V.t) ctx) lval f a fctx =
let threadspawn (ctx:(D.t, G.t, C.t, V.t) ctx) ~multiple lval f a fctx =
let sides = ref [] in
let emits = ref [] in
let ctx'' = outer_ctx "threadspawn" ~sides ~emits ctx in
let fctx'' = outer_ctx "threadspawn" ~sides ~emits fctx in
let f post_all (n,(module S:MCPSpec),(d,fd)) =
let ctx' : (S.D.t, S.G.t, S.C.t, S.V.t) ctx = inner_ctx "threadspawn" ~post_all ctx'' n d in
let fctx' : (S.D.t, S.G.t, S.C.t, S.V.t) ctx = inner_ctx "threadspawn" ~post_all fctx'' n fd in
n, repr @@ S.threadspawn ctx' lval f a fctx'
n, repr @@ S.threadspawn ~multiple ctx' lval f a fctx'
in
let d, q = map_deadcode f @@ spec_list2 ctx.local fctx.local in
do_sideg ctx !sides;
Expand Down
4 changes: 2 additions & 2 deletions src/analyses/mallocFresh.ml
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ struct
| None -> ctx.local
| Some lval -> assign_lval (Analyses.ask_of_ctx ctx) lval ctx.local

let threadenter ctx lval f args =
let threadenter ctx ~multiple lval f args =
[D.empty ()]

let threadspawn ctx lval f args fctx =
let threadspawn ctx ~multiple lval f args fctx =
D.empty ()

module A =
Expand Down
4 changes: 2 additions & 2 deletions src/analyses/malloc_null.ml
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ struct
let name () = "malloc_null"

let startstate v = D.empty ()
let threadenter ctx lval f args = [D.empty ()]
let threadspawn ctx lval f args fctx = ctx.local
let threadenter ctx ~multiple lval f args = [D.empty ()]
let threadspawn ctx ~multiple lval f args fctx = ctx.local
let exitstate v = D.empty ()

let init marshal =
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/modifiedSinceLongjmp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ struct
ctx.local

let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]
let threadenter ctx ~multiple lval f args = [D.bot ()]
let exitstate v = D.top ()

let query ctx (type a) (q: a Queries.t): a Queries.result =
Expand Down
4 changes: 2 additions & 2 deletions src/analyses/mutexTypeAnalysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ struct
| _ -> ctx.local

let startstate v = D.bot ()
let threadenter ctx lval f args = [D.top ()]
let threadspawn ctx lval f args fctx = ctx.local
let threadenter ctx ~multiple lval f args = [D.top ()]
let threadspawn ctx ~multiple lval f args fctx = ctx.local
let exitstate v = D.top ()

let query ctx (type a) (q: a Queries.t): a Queries.result =
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/poisonVariables.ml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ struct
VS.join au ctx.local

let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]
let threadenter ctx ~multiple lval f args = [D.bot ()]
let exitstate v = D.top ()

let event ctx e octx =
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/pthreadSignals.ml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ struct
| _ -> ctx.local

let startstate v = Signals.empty ()
let threadenter ctx lval f args = [ctx.local]
let threadenter ctx ~multiple lval f args = [ctx.local]
let exitstate v = Signals.empty ()
end

Expand Down
4 changes: 2 additions & 2 deletions src/analyses/region.ml
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,9 @@ struct
let startstate v =
`Lifted (RegMap.bot ())

let threadenter ctx lval f args =
let threadenter ctx ~multiple lval f args =
[`Lifted (RegMap.bot ())]
let threadspawn ctx lval f args fctx = ctx.local
let threadspawn ctx ~multiple lval f args fctx = ctx.local

let exitstate v = `Lifted (RegMap.bot ())

Expand Down
4 changes: 2 additions & 2 deletions src/analyses/spec.ml
Original file line number Diff line number Diff line change
Expand Up @@ -487,8 +487,8 @@ struct


let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]
let threadspawn ctx lval f args fctx = ctx.local
let threadenter ctx ~multiple lval f args = [D.bot ()]
let threadspawn ctx ~multiple lval f args fctx = ctx.local
let exitstate v = D.bot ()
end

Expand Down
4 changes: 2 additions & 2 deletions src/analyses/stackTrace.ml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct
ctx.local (* keep local as opposed to IdentitySpec *)

let startstate v = D.bot ()
let threadenter ctx lval f args = [D.bot ()]
let threadenter ctx ~multiple lval f args = [D.bot ()]
let exitstate v = D.top ()
end

Expand All @@ -45,7 +45,7 @@ struct
let startstate v = D.bot ()
let exitstate v = D.top ()

let threadenter ctx lval f args =
let threadenter ctx ~multiple lval f args =
[D.push !Tracing.current_loc ctx.local]
end

Expand Down
4 changes: 2 additions & 2 deletions src/analyses/symbLocks.ml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ struct
let name () = "symb_locks"

let startstate v = D.top ()
let threadenter ctx lval f args = [D.top ()]
let threadspawn ctx lval f args fctx = ctx.local
let threadenter ctx ~multiple lval f args = [D.top ()]
let threadspawn ctx ~multiple lval f args fctx = ctx.local
let exitstate v = D.top ()

let branch ctx exp tv = ctx.local
Expand Down
4 changes: 2 additions & 2 deletions src/analyses/taintPartialContexts.ml
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ struct
d

let startstate v = D.bot ()
let threadenter ctx lval f args =
let threadenter ctx ~multiple lval f args =
[D.bot ()]
let threadspawn ctx lval f args fctx =
let threadspawn ctx ~multiple lval f args fctx =
match lval with
| Some lv -> taint_lval ctx lv
| None -> ctx.local
Expand Down
Loading
Loading