[quandary] don't create dummy global reads for Drawable IDs in C++

Reviewed By: jvillard

Differential Revision: D6110257

fbshipit-source-id: 66edb63
master
Sam Blackshear 7 years ago committed by Facebook Github Bot
parent 3df1e52928
commit 12d73e67dc

@ -373,44 +373,52 @@ module Make (TaintSpecification : TaintSpec.S) = struct
TaintDomain.trace_fold add_to_caller_tree summary caller_access_tree TaintDomain.trace_fold add_to_caller_tree summary caller_access_tree
let preprocess_exp exp = let preprocess_exp exp = function
(* hack: preprocessor for expressions to convert some literals into dummy field reads. needed in | Config.Java ->
Java when we want to us an R.id.whatever field as a source, but the compiler inlines the (* hack: preprocessor for expressions to convert some literals into dummy field reads.
field read because it's a static final constant *) needed in Java when we want to us an R.id.whatever field as a source, but the compiler
let convert_id_literal_to_read = function inlines the field read because it's a static final constant *)
| HilExp.Constant Const.Cint i as e -> let convert_id_literal_to_read = function
let int_value = | HilExp.Constant Const.Cint i as e ->
try IntLit.to_int i let int_value =
with _ -> 0 try IntLit.to_int i
in with _ -> 0
(* heuristic to decide if this looks like a resource ID *) in
if Int.abs int_value > 1000 then (* heuristic to decide if this looks like a resource ID *)
(* convert this resource ID literal into a dummy field read *) if Int.abs int_value > 1000 then
let dummy_pvar = (* convert this resource ID literal into a dummy field read *)
Pvar.mk_global let dummy_pvar =
(Mangled.from_string Pvar.mk_global
(F.sprintf "%s_%d" AndroidFramework.drawable_prefix int_value)) (Mangled.from_string
Pvar.TUExtern (F.sprintf "%s_%d" AndroidFramework.drawable_prefix int_value))
in Pvar.TUExtern
HilExp.AccessPath ((Var.of_pvar dummy_pvar, Typ.mk (Typ.Tint Typ.IInt)), []) in
else e HilExp.AccessPath ((Var.of_pvar dummy_pvar, Typ.mk (Typ.Tint Typ.IInt)), [])
| e -> else e
e | e ->
in e
convert_id_literal_to_read exp in
convert_id_literal_to_read exp
| _ ->
exp
(* avoid overhead of allocating new list in the (very) common case that preprocess is a no-op *) (* avoid overhead of allocating new list in the (very) common case that preprocess is a no-op *)
let preprocess_exps exps = let preprocess_exps exps language =
if List.exists ~f:(fun exp -> not (phys_equal exp (preprocess_exp exp))) exps then match language with
List.map ~f:preprocess_exp exps | Config.Java ->
else exps if List.exists ~f:(fun exp -> not (phys_equal exp (preprocess_exp exp language))) exps
then List.map ~f:(fun exp -> preprocess_exp exp language) exps
else exps
| _ ->
exps
let exec_instr (astate: Domain.astate) (proc_data: extras ProcData.t) _ (instr: HilInstr.t) = let exec_instr (astate: Domain.astate) (proc_data: extras ProcData.t) _ (instr: HilInstr.t) =
(* not all sinks are function calls; we might want to treat an array or field access as a (* not all sinks are function calls; we might want to treat an array or field access as a
sink too. do this by pretending an access is a call to a dummy function and using the sink too. do this by pretending an access is a call to a dummy function and using the
existing machinery for adding function call sinks *) existing machinery for adding function call sinks *)
let language = Typ.Procname.get_language (Procdesc.get_proc_name proc_data.pdesc) in
let add_sinks_for_access_path (_, accesses) loc astate = let add_sinks_for_access_path (_, accesses) loc astate =
let add_sinks_for_access astate_acc = function let add_sinks_for_access astate_acc = function
| AccessPath.FieldAccess _ | AccessPath.ArrayAccess (_, []) -> | AccessPath.FieldAccess _ | AccessPath.ArrayAccess (_, []) ->
@ -475,14 +483,14 @@ module Make (TaintSpecification : TaintSpec.S) = struct
`return null` in a void function *) `return null` in a void function *)
astate astate
| Assign (lhs_access_path, rhs_exp, loc) -> | Assign (lhs_access_path, rhs_exp, loc) ->
let rhs_exp = preprocess_exp rhs_exp in let rhs_exp = preprocess_exp rhs_exp language in
add_sources_sinks_for_exp rhs_exp loc astate add_sources_sinks_for_exp rhs_exp loc astate
|> add_sinks_for_access_path lhs_access_path loc |> exec_write lhs_access_path rhs_exp |> add_sinks_for_access_path lhs_access_path loc |> exec_write lhs_access_path rhs_exp
| Assume (assume_exp, _, _, loc) -> | Assume (assume_exp, _, _, loc) ->
let assume_exp = preprocess_exp assume_exp in let assume_exp = preprocess_exp assume_exp language in
add_sources_sinks_for_exp assume_exp loc astate add_sources_sinks_for_exp assume_exp loc astate
| Call (ret_opt, Direct called_pname, actuals, call_flags, callee_loc) -> | Call (ret_opt, Direct called_pname, actuals, call_flags, callee_loc) ->
let actuals = preprocess_exps actuals in let actuals = preprocess_exps actuals language in
let astate = let astate =
List.fold List.fold
~f:(fun acc exp -> add_sources_sinks_for_exp exp callee_loc acc) ~f:(fun acc exp -> add_sources_sinks_for_exp exp callee_loc acc)

Loading…
Cancel
Save