Skip to content

Commit ba2d79b

Browse files
arthaudfacebook-github-bot
authored andcommitted
Add functions to add or get features out of taint representations
Summary: A very recurrent pattern in our codebase is to gather or add features or breadcrumb on a taint abstraction. For now, this is usually done with a fold on the abstract domain. Let's add helper functions to add or gather breadcrumbs and features. This will make refactoring easier when changing the abstraction for the feature set, for instance splitting via-features and breadcrumbs, or implementing local features. Reviewed By: dkgi Differential Revision: D30761500 fbshipit-source-id: 5e7dc8e180b38b302b470cdb32ca40b9ffbfdb2a
1 parent 3f13206 commit ba2d79b

File tree

4 files changed

+127
-135
lines changed

4 files changed

+127
-135
lines changed

source/interprocedural_analyses/taint/backwardAnalysis.ml

Lines changed: 25 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -203,13 +203,7 @@ module AnalysisInstance (FunctionContext : FUNCTION_CONTEXT) = struct
203203
(* No special path handling for side effect taint *)
204204
[[]]
205205
in
206-
let breadcrumbs =
207-
BackwardTaint.fold
208-
Features.SimpleSet.Self
209-
element
210-
~f:Features.gather_breadcrumbs
211-
~init:Features.SimpleSet.bottom
212-
in
206+
let breadcrumbs = BackwardTaint.breadcrumbs element in
213207
let tito_depth =
214208
BackwardTaint.fold
215209
TraceLength.Self
@@ -238,8 +232,8 @@ module AnalysisInstance (FunctionContext : FUNCTION_CONTEXT) = struct
238232
~f:(fun taint extra_path ->
239233
read_tree extra_path taint_to_propagate
240234
|> BackwardState.Tree.collapse
241-
~transform:(BackwardTaint.add_features Features.tito_broadening)
242-
|> BackwardTaint.transform Features.SimpleSet.Self Add ~f:breadcrumbs
235+
~transform:(BackwardTaint.add_breadcrumbs Features.tito_broadening)
236+
|> BackwardTaint.add_breadcrumbs breadcrumbs
243237
|> BackwardTaint.transform
244238
TraceLength.Self
245239
(Context (BackwardTaint.kind, Map))
@@ -254,8 +248,8 @@ module AnalysisInstance (FunctionContext : FUNCTION_CONTEXT) = struct
254248
in
255249
let add_tito_feature_and_position leaf_taint =
256250
leaf_taint
257-
|> FlowDetails.transform Features.TitoPositionSet.Element Add ~f:location
258-
|> FlowDetails.transform Features.SimpleSet.Element Add ~f:Features.tito
251+
|> FlowDetails.add_tito_position location
252+
|> FlowDetails.add_breadcrumb Features.tito
259253
in
260254
BackwardState.read
261255
~transform_non_leaves
@@ -315,19 +309,16 @@ module AnalysisInstance (FunctionContext : FUNCTION_CONTEXT) = struct
315309
let state =
316310
match AccessPath.of_expression ~resolution argument with
317311
| Some { AccessPath.root; path } ->
318-
let features_to_add =
312+
let breadcrumbs_to_add =
319313
BackwardState.Tree.filter_by_kind ~kind:Sinks.AddFeatureToArgument sink_taint
320-
|> BackwardTaint.fold
321-
Features.SimpleSet.Self
322-
~f:Features.gather_breadcrumbs
323-
~init:Features.SimpleSet.bottom
314+
|> BackwardTaint.breadcrumbs
324315
in
325-
if Features.SimpleSet.is_bottom features_to_add then
316+
if Features.SimpleSet.is_bottom breadcrumbs_to_add then
326317
state
327318
else
328319
let taint =
329320
BackwardState.read state.taint ~root ~path
330-
|> BackwardState.Tree.transform Features.SimpleSet.Self Add ~f:features_to_add
321+
|> BackwardState.Tree.add_breadcrumbs breadcrumbs_to_add
331322
in
332323
{ taint = BackwardState.assign ~root ~path taint state.taint }
333324
| None -> state
@@ -348,9 +339,9 @@ module AnalysisInstance (FunctionContext : FUNCTION_CONTEXT) = struct
348339
|> Features.SimpleSet.add Features.obscure
349340
in
350341
BackwardState.Tree.collapse
351-
~transform:(BackwardTaint.add_features Features.tito_broadening)
342+
~transform:(BackwardTaint.add_breadcrumbs Features.tito_broadening)
352343
call_taint
353-
|> BackwardTaint.transform Features.SimpleSet.Self Add ~f:breadcrumbs
344+
|> BackwardTaint.add_breadcrumbs breadcrumbs
354345
|> BackwardState.Tree.create_leaf
355346
else
356347
BackwardState.Tree.bottom
@@ -387,9 +378,9 @@ module AnalysisInstance (FunctionContext : FUNCTION_CONTEXT) = struct
387378
in
388379
let obscure_taint =
389380
BackwardState.Tree.collapse
390-
~transform:(BackwardTaint.add_features Features.tito_broadening)
381+
~transform:(BackwardTaint.add_breadcrumbs Features.tito_broadening)
391382
call_taint
392-
|> BackwardTaint.transform Features.SimpleSet.Element Add ~f:Features.obscure
383+
|> BackwardTaint.add_breadcrumb Features.obscure
393384
|> BackwardState.Tree.create_leaf
394385
in
395386
let state =
@@ -676,7 +667,7 @@ module AnalysisInstance (FunctionContext : FUNCTION_CONTEXT) = struct
676667
BackwardState.Tree.join
677668
taint
678669
(get_taint (Some (AccessPath.create (Root.Variable "$all") [])) state)
679-
|> BackwardState.Tree.transform Features.SimpleSet.Element Add ~f:Features.lambda
670+
|> BackwardState.Tree.add_breadcrumb Features.lambda
680671
in
681672
let all_assignee =
682673
Node.create
@@ -937,11 +928,7 @@ module AnalysisInstance (FunctionContext : FUNCTION_CONTEXT) = struct
937928
| Name
938929
(Name.Attribute
939930
{ base = { Node.value = Expression.String _; _ }; attribute = "format"; _ }) ->
940-
BackwardState.Tree.transform
941-
Features.SimpleSet.Element
942-
Add
943-
~f:Features.format_string
944-
taint
931+
BackwardState.Tree.add_breadcrumb Features.format_string taint
945932
| _ -> taint
946933
in
947934
match FunctionContext.get_callees ~location ~call:{ Call.callee; arguments } with
@@ -1003,13 +990,7 @@ module AnalysisInstance (FunctionContext : FUNCTION_CONTEXT) = struct
1003990
taint)
1004991
~init:taint
1005992
in
1006-
let taint =
1007-
BackwardState.Tree.transform
1008-
Features.SimpleSet.Element
1009-
Add
1010-
~f:Features.format_string
1011-
taint
1012-
in
993+
let taint = BackwardState.Tree.add_breadcrumb Features.format_string taint in
1013994
List.fold
1014995
expressions
1015996
~f:(fun state expression -> analyze_expression ~resolution ~taint ~state ~expression)
@@ -1034,9 +1015,7 @@ module AnalysisInstance (FunctionContext : FUNCTION_CONTEXT) = struct
10341015
match ComparisonOperator.override ~location comparison with
10351016
| Some override -> analyze_expression ~resolution ~taint ~state ~expression:override
10361017
| None ->
1037-
let taint =
1038-
BackwardState.Tree.transform Features.SimpleSet.Self Add ~f:Features.type_bool taint
1039-
in
1018+
let taint = BackwardState.Tree.add_breadcrumbs Features.type_bool taint in
10401019
analyze_expression ~resolution ~taint ~state ~expression:right
10411020
|> fun state -> analyze_expression ~resolution ~taint ~state ~expression:left)
10421021
| Call { callee; arguments } ->
@@ -1111,16 +1090,9 @@ module AnalysisInstance (FunctionContext : FUNCTION_CONTEXT) = struct
11111090
let global_model = Model.get_global_model ~resolution ~expression ~location in
11121091
let add_tito_features taint =
11131092
let attribute_features =
1114-
global_model |> Model.GlobalModel.get_tito |> BackwardState.Tree.get_all_features
1093+
global_model |> Model.GlobalModel.get_tito |> BackwardState.Tree.features
11151094
in
1116-
if not (Features.SimpleSet.is_bottom attribute_features) then
1117-
BackwardState.Tree.transform
1118-
Features.SimpleSet.Self
1119-
Add
1120-
~f:attribute_features
1121-
taint
1122-
else
1123-
taint
1095+
BackwardState.Tree.add_breadcrumbs attribute_features taint
11241096
in
11251097

11261098
let apply_attribute_sanitizers taint =
@@ -1392,12 +1364,12 @@ let extract_tito_and_sink_models define ~is_constructor ~resolution ~existing_ba
13921364
BackwardState.Tree.essential tree
13931365
in
13941366
BackwardState.Tree.shape
1395-
~transform:(BackwardTaint.add_features Features.widen_broadening)
1367+
~transform:(BackwardTaint.add_breadcrumbs Features.widen_broadening)
13961368
tree
13971369
~mold:essential
1398-
|> BackwardState.Tree.transform Features.SimpleSet.Self Add ~f:type_breadcrumbs
1370+
|> BackwardState.Tree.add_breadcrumbs type_breadcrumbs
13991371
|> BackwardState.Tree.limit_to
1400-
~transform:(BackwardTaint.add_features Features.widen_broadening)
1372+
~transform:(BackwardTaint.add_breadcrumbs Features.widen_broadening)
14011373
~width:maximum_model_width
14021374
|> BackwardState.Tree.approximate_return_access_paths ~maximum_return_access_path_length
14031375
in
@@ -1426,16 +1398,7 @@ let extract_tito_and_sink_models define ~is_constructor ~resolution ~existing_ba
14261398
BackwardState.Tree.prune_maximum_length maximum_tito_depth candidate_tree
14271399
| _ -> candidate_tree
14281400
in
1429-
let candidate_tree =
1430-
if Features.SimpleSet.is_bottom features_to_attach then
1431-
candidate_tree
1432-
else
1433-
BackwardState.Tree.transform
1434-
Features.SimpleSet.Self
1435-
Add
1436-
~f:features_to_attach
1437-
candidate_tree
1438-
in
1401+
let candidate_tree = BackwardState.Tree.add_breadcrumbs features_to_attach candidate_tree in
14391402
let number_of_paths =
14401403
BackwardState.Tree.fold
14411404
BackwardState.Tree.Path
@@ -1445,7 +1408,7 @@ let extract_tito_and_sink_models define ~is_constructor ~resolution ~existing_ba
14451408
in
14461409
if number_of_paths > TaintConfiguration.maximum_tito_leaves then
14471410
BackwardState.Tree.collapse_to
1448-
~transform:(BackwardTaint.add_features Features.widen_broadening)
1411+
~transform:(BackwardTaint.add_breadcrumbs Features.widen_broadening)
14491412
~depth:0
14501413
candidate_tree
14511414
else
@@ -1477,10 +1440,7 @@ let extract_tito_and_sink_models define ~is_constructor ~resolution ~existing_ba
14771440
~attach_to_kind:Sinks.Attach
14781441
existing_backward.TaintResult.Backward.sink_taint
14791442
in
1480-
if not (Features.SimpleSet.is_bottom features_to_attach) then
1481-
BackwardState.Tree.transform Features.SimpleSet.Self Add ~f:features_to_attach sink_taint
1482-
else
1483-
sink_taint
1443+
BackwardState.Tree.add_breadcrumbs features_to_attach sink_taint
14841444
in
14851445
TaintResult.Backward.
14861446
{

source/interprocedural_analyses/taint/domains.ml

Lines changed: 74 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,14 @@ module FlowDetails = struct
223223
transform Features.TitoPositionSet.Self Map ~f:(fun _ -> Features.TitoPositionSet.bottom)
224224

225225

226+
let add_tito_position position = transform Features.TitoPositionSet.Element Add ~f:position
227+
228+
let add_breadcrumb breadcrumb = transform Features.SimpleSet.Element Add ~f:breadcrumb
229+
230+
let add_breadcrumbs breadcrumbs = transform Features.SimpleSet.Self Add ~f:breadcrumbs
231+
232+
let features = get Slots.SimpleFeature
233+
226234
let product_pp = pp (* shadow *)
227235

228236
let pp formatter = Format.fprintf formatter "FlowDetails(%a)" product_pp
@@ -252,7 +260,13 @@ module type TAINT_DOMAIN = sig
252260

253261
val trace_info : TraceInfo.t Abstract.Domain.part
254262

255-
val add_features : Features.SimpleSet.t -> t -> t
263+
val add_breadcrumb : Features.Simple.t -> t -> t
264+
265+
val add_breadcrumbs : Features.SimpleSet.t -> t -> t
266+
267+
val breadcrumbs : t -> Features.SimpleSet.t
268+
269+
val features : t -> Features.SimpleSet.t
256270

257271
val transform_on_widening_collapse : t -> t
258272

@@ -384,12 +398,11 @@ end = struct
384398
|> Features.FirstField.to_json
385399
in
386400
( List.concat [first_index_breadcrumbs; first_field_breadcrumbs; breadcrumbs],
387-
FlowDetails.(
388-
fold
389-
Features.ReturnAccessPathSet.Element
390-
~f:gather_return_access_path
391-
~init:leaves
392-
features) )
401+
FlowDetails.fold
402+
Features.ReturnAccessPathSet.Element
403+
~f:gather_return_access_path
404+
~init:leaves
405+
features )
393406
in
394407
let tito_positions =
395408
FlowDetails.get FlowDetails.Slots.TitoPosition features
@@ -432,7 +445,27 @@ end = struct
432445
create_json ~trace_info_to_json:(TraceInfo.to_external_json ~filename_lookup)
433446

434447

435-
let add_features features = transform Features.SimpleSet.Self Add ~f:features
448+
let add_breadcrumb breadcrumb = transform Features.SimpleSet.Element Add ~f:breadcrumb
449+
450+
let add_breadcrumbs breadcrumbs taint =
451+
if Features.SimpleSet.is_bottom breadcrumbs || Features.SimpleSet.is_empty breadcrumbs then
452+
taint
453+
else
454+
transform Features.SimpleSet.Self Add ~f:breadcrumbs taint
455+
456+
457+
let features taint =
458+
let gather_features to_add features = Features.SimpleSet.add_set features ~to_add in
459+
fold Features.SimpleSet.Self ~f:gather_features ~init:Features.SimpleSet.bottom taint
460+
461+
462+
let breadcrumbs taint =
463+
fold
464+
Features.SimpleSet.Self
465+
~f:Features.gather_breadcrumbs
466+
~init:Features.SimpleSet.bottom
467+
taint
468+
436469

437470
let transform_on_widening_collapse =
438471
(* using an always-feature here would break the widening invariant: a <= a widen b *)
@@ -444,7 +477,7 @@ end = struct
444477
{ element = Simple.Breadcrumb Breadcrumb.IssueBroadening; in_under = false };
445478
]
446479
in
447-
add_features broadening
480+
add_breadcrumbs broadening
448481

449482

450483
let prune_maximum_length maximum_length =
@@ -571,13 +604,31 @@ module MakeTaintTree (Taint : TAINT_DOMAIN) () = struct
571604
|> collapse ~transform:Fn.id
572605

573606

574-
let get_all_features taint_tree =
575-
let gather_features to_add features = Features.SimpleSet.add_set features ~to_add in
576-
fold Features.SimpleSet.Self ~f:gather_features ~init:Features.SimpleSet.bottom taint_tree
607+
let breadcrumbs taint_tree =
608+
fold
609+
Features.SimpleSet.Self
610+
~f:Features.gather_breadcrumbs
611+
~init:Features.SimpleSet.bottom
612+
taint_tree
577613
end
578614

579615
module MakeTaintEnvironment (Taint : TAINT_DOMAIN) () = struct
580-
module Tree = MakeTaintTree (Taint) ()
616+
module Tree = struct
617+
include MakeTaintTree (Taint) ()
618+
619+
let add_breadcrumb breadcrumb = transform Features.SimpleSet.Element Add ~f:breadcrumb
620+
621+
let add_breadcrumbs breadcrumbs taint_tree =
622+
if Features.SimpleSet.is_bottom breadcrumbs || Features.SimpleSet.is_empty breadcrumbs then
623+
taint_tree
624+
else
625+
transform Features.SimpleSet.Self Add ~f:breadcrumbs taint_tree
626+
627+
628+
let features taint_tree =
629+
let gather_features to_add features = Features.SimpleSet.add_set features ~to_add in
630+
fold Features.SimpleSet.Self ~f:gather_features ~init:Features.SimpleSet.bottom taint_tree
631+
end
581632

582633
include
583634
Abstract.MapDomain.Make
@@ -646,12 +697,20 @@ module MakeTaintEnvironment (Taint : TAINT_DOMAIN) () = struct
646697
647698
let roots environment = fold Key ~f:List.cons ~init:[] environment
648699
700+
let add_breadcrumb breadcrumb = transform Features.SimpleSet.Element Add ~f:breadcrumb
701+
702+
let add_breadcrumbs breadcrumbs taint_tree =
703+
if Features.SimpleSet.is_bottom breadcrumbs || Features.SimpleSet.is_empty breadcrumbs then
704+
taint_tree
705+
else
706+
transform Features.SimpleSet.Self Add ~f:breadcrumbs taint_tree
707+
708+
649709
let extract_features_to_attach ~root ~attach_to_kind taint =
650-
let gather_features to_add features = Features.SimpleSet.add_set features ~to_add in
651710
read ~root ~path:[] taint
652711
|> Tree.transform Taint.kind Filter ~f:(Taint.equal_kind attach_to_kind)
653712
|> Tree.collapse ~transform:Fn.id
654-
|> Taint.fold Features.SimpleSet.Self ~f:gather_features ~init:Features.SimpleSet.bottom
713+
|> Taint.features
655714
end
656715
657716
module ForwardState = MakeTaintEnvironment (ForwardTaint) ()

source/interprocedural_analyses/taint/flow.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ let generate_source_sink_matches ~location ~source_tree ~sink_tree =
5656
let make_source_sink_matches (path, sink_taint) matches =
5757
let source_taint =
5858
ForwardState.Tree.read path source_tree
59-
|> ForwardState.Tree.collapse ~transform:(ForwardTaint.add_features Features.issue_broadening)
59+
|> ForwardState.Tree.collapse
60+
~transform:(ForwardTaint.add_breadcrumbs Features.issue_broadening)
6061
in
6162
if ForwardTaint.is_bottom source_taint then
6263
matches
@@ -327,7 +328,7 @@ let code_metadata () =
327328
let compute_triggered_sinks ~triggered_sinks ~location ~source_tree ~sink_tree =
328329
let partial_sinks_to_taint =
329330
BackwardState.Tree.collapse
330-
~transform:(BackwardTaint.add_features Features.issue_broadening)
331+
~transform:(BackwardTaint.add_breadcrumbs Features.issue_broadening)
331332
sink_tree
332333
|> BackwardTaint.partition BackwardTaint.kind ByFilter ~f:(function
333334
| Sinks.PartialSink { Sinks.kind; label } -> Some { Sinks.kind; label }

0 commit comments

Comments
 (0)