From 42c298ec647d6f77789c5e63f49dc56d64de4418 Mon Sep 17 00:00:00 2001 From: David Pichardie Date: Wed, 13 Nov 2024 08:44:24 -0800 Subject: [PATCH] [inferpython] reorganize tainting tests with imports Summary: now that we have a basic import system, we can make these tests more pretty Reviewed By: geralt-encore Differential Revision: D65670194 Privacy Context Container: L1208441 fbshipit-source-id: da4917d2bd1672630d3774fb63129ad9d07a2b68 --- .../codetoanalyze/python/pulse/.inferconfig | 8 +--- .../codetoanalyze/python/pulse/issues.exp | 16 +++---- .../codetoanalyze/python/pulse/level0.py | 20 ++++---- .../codetoanalyze/python/pulse/level1.py | 47 +++++++++++-------- .../python/pulse/simple-import.py | 10 ++-- .../tests/codetoanalyze/python/pulse/taint.py | 10 ++++ 6 files changed, 60 insertions(+), 51 deletions(-) create mode 100644 infer/tests/codetoanalyze/python/pulse/taint.py diff --git a/infer/tests/codetoanalyze/python/pulse/.inferconfig b/infer/tests/codetoanalyze/python/pulse/.inferconfig index 3d22a7a0ed..82cb7c50ba 100644 --- a/infer/tests/codetoanalyze/python/pulse/.inferconfig +++ b/infer/tests/codetoanalyze/python/pulse/.inferconfig @@ -4,14 +4,10 @@ "pulse-specialization-partial": true, "pulse-taint-short-traces": true, "pulse-taint-sources": [ - { "procedure": "level0::taint_source" }, - { "procedure": "level1::taint_source" } + { "procedure": "taint::source" } ], "pulse-taint-sinks": [ - { "procedure": "level0::taint_sink", - "taint_target": ["ArgumentPositions", [1]] - }, - { "procedure": "level1::taint_sink", + { "procedure": "taint::sink", "taint_target": ["ArgumentPositions", [1]] } ] diff --git a/infer/tests/codetoanalyze/python/pulse/issues.exp b/infer/tests/codetoanalyze/python/pulse/issues.exp index a19739c8e9..fa4ee81256 100644 --- a/infer/tests/codetoanalyze/python/pulse/issues.exp +++ b/infer/tests/codetoanalyze/python/pulse/issues.exp @@ -1,8 +1,8 @@ -level0.py, level0::__module_body__, 15, TAINT_ERROR, no_bucket, ERROR, [in call to `closure:level0:1.call`,source of the taint here: value returned from `level0::taint_source` with kind `Simple`,return from call to `closure:level0:1.call`,when calling `closure:level0:0.call` here,flows to this sink: value passed as argument `#1` to `level0::taint_sink` with kind `Simple`], source: level0::taint_source, sink: level0::taint_sink, tainted expression: UNKNOWN -level0.py, level0::__module_body__, 23, TAINT_ERROR, no_bucket, ERROR, [in call to `closure:level0:1.call`,source of the taint here: value returned from `level0::taint_source` with kind `Simple`,return from call to `closure:level0:1.call`,when calling `closure:level0:0.call` here,flows to this sink: value passed as argument `#1` to `level0::taint_sink` with kind `Simple`], source: level0::taint_source, sink: level0::taint_sink, tainted expression: UNKNOWN -level1.py, level1::basic_flow_bad, 2, TAINT_ERROR, no_bucket, ERROR, [in call to `closure:level1:0.call`,source of the taint here: value returned from `level1::taint_source` with kind `Simple`,return from call to `closure:level1:0.call`,when calling `closure:level1:1.call` here,flows to this sink: value passed as argument `#1` to `level1::taint_sink` with kind `Simple`], source: level1::taint_source, sink: level1::taint_sink, tainted expression: UNKNOWN -level1.py, level1::call_fst_bad, 2, TAINT_ERROR, no_bucket, ERROR, [in call to `closure:level1:0.call`,source of the taint here: value returned from `level1::taint_source` with kind `Simple`,return from call to `closure:level1:0.call`,when calling `closure:level1:1.call` here,flows to this sink: value passed as argument `#1` to `level1::taint_sink` with kind `Simple`], source: level1::taint_source, sink: level1::taint_sink, tainted expression: UNKNOWN -level1.py, level1::call_sink_fst_arg_bad, 1, TAINT_ERROR, no_bucket, ERROR, [in call to `closure:level1:0.call`,source of the taint here: value returned from `level1::taint_source` with kind `Simple`,return from call to `closure:level1:0.call`,when calling `closure:level1:7.call` here,when calling `level1::sink_fst_arg` here,when calling `closure:level1:1.call` here,flows to this sink: value passed as argument `#1` to `level1::taint_sink` with kind `Simple`], source: level1::taint_source, sink: level1::taint_sink, tainted expression: closure:level1:0.call() -level1.py, level1::call_taint_sink_on_global_bad2, 3, TAINT_ERROR, no_bucket, ERROR, [in call to `closure:level1:0.call`,source of the taint here: value returned from `level1::taint_source` with kind `Simple`,return from call to `closure:level1:0.call`,when calling `closure:level1:1.call` here,flows to this sink: value passed as argument `#1` to `level1::taint_sink` with kind `Simple`], source: level1::taint_source, sink: level1::taint_sink, tainted expression: UNKNOWN -level1.py, level1::__module_body__, 60, TAINT_ERROR, no_bucket, ERROR, [in call to `closure:level1:2.call`,in call to `level1::basic_flow_bad`,in call to `closure:level1:0.call`,source of the taint here: value returned from `level1::taint_source` with kind `Simple`,return from call to `closure:level1:0.call`,return from call to `level1::basic_flow_bad`,return from call to `closure:level1:2.call`,when calling `closure:level1:10.call` here,when calling `level1::call_taint_sink_on_global_bad1` here,when calling `closure:level1:1.call` here,flows to this sink: value passed as argument `#1` to `level1::taint_sink` with kind `Simple`], source: level1::taint_source, sink: level1::taint_sink, tainted expression: globals->g -simple-import.py, simple-import::basic_flow_bad, 2, TAINT_ERROR, no_bucket, ERROR, [in call to `closure:level1:0.call`,source of the taint here: value returned from `level1::taint_source` with kind `Simple`,return from call to `closure:level1:0.call`,when calling `closure:level1:1.call` here,flows to this sink: value passed as argument `#1` to `level1::taint_sink` with kind `Simple`], source: level1::taint_source, sink: level1::taint_sink, tainted expression: UNKNOWN +level0.py, level0::__module_body__, 11, TAINT_ERROR, no_bucket, ERROR, [in call to `closure:taint:1.call`,source of the taint here: value returned from `taint::source` with kind `Simple`,return from call to `closure:taint:1.call`,when calling `closure:taint:0.call` here,flows to this sink: value passed as argument `#1` to `taint::sink` with kind `Simple`], source: taint::source, sink: taint::sink, tainted expression: UNKNOWN +level0.py, level0::__module_body__, 19, TAINT_ERROR, no_bucket, ERROR, [in call to `closure:taint:1.call`,source of the taint here: value returned from `taint::source` with kind `Simple`,return from call to `closure:taint:1.call`,when calling `closure:taint:0.call` here,flows to this sink: value passed as argument `#1` to `taint::sink` with kind `Simple`], source: taint::source, sink: taint::sink, tainted expression: UNKNOWN +level1.py, level1::basic_flow_bad, 2, TAINT_ERROR, no_bucket, ERROR, [in call to `closure:taint:1.call`,source of the taint here: value returned from `taint::source` with kind `Simple`,return from call to `closure:taint:1.call`,when calling `closure:taint:0.call` here,flows to this sink: value passed as argument `#1` to `taint::sink` with kind `Simple`], source: taint::source, sink: taint::sink, tainted expression: UNKNOWN +level1.py, level1::call_fst_bad, 2, TAINT_ERROR, no_bucket, ERROR, [in call to `closure:taint:1.call`,source of the taint here: value returned from `taint::source` with kind `Simple`,return from call to `closure:taint:1.call`,when calling `closure:taint:0.call` here,flows to this sink: value passed as argument `#1` to `taint::sink` with kind `Simple`], source: taint::source, sink: taint::sink, tainted expression: UNKNOWN +level1.py, level1::call_sink_fst_arg_bad, 1, TAINT_ERROR, no_bucket, ERROR, [in call to `closure:taint:1.call`,source of the taint here: value returned from `taint::source` with kind `Simple`,return from call to `closure:taint:1.call`,when calling `closure:level1:5.call` here,when calling `level1::sink_fst_arg` here,when calling `closure:taint:0.call` here,flows to this sink: value passed as argument `#1` to `taint::sink` with kind `Simple`], source: taint::source, sink: taint::sink, tainted expression: closure:taint:1.call() +level1.py, level1::call_taint_sink_on_global_bad2, 3, TAINT_ERROR, no_bucket, ERROR, [in call to `closure:taint:1.call`,source of the taint here: value returned from `taint::source` with kind `Simple`,return from call to `closure:taint:1.call`,when calling `closure:taint:0.call` here,flows to this sink: value passed as argument `#1` to `taint::sink` with kind `Simple`], source: taint::source, sink: taint::sink, tainted expression: UNKNOWN +level1.py, level1::__module_body__, 67, TAINT_ERROR, no_bucket, ERROR, [in call to `closure:taint:1.call`,source of the taint here: value returned from `taint::source` with kind `Simple`,return from call to `closure:taint:1.call`,when calling `closure:level1:8.call` here,when calling `level1::call_taint_sink_on_global_bad1` here,when calling `closure:taint:0.call` here,flows to this sink: value passed as argument `#1` to `taint::sink` with kind `Simple`], source: taint::source, sink: taint::sink, tainted expression: globals->g +simple-import.py, simple-import::basic_flow_bad, 2, TAINT_ERROR, no_bucket, ERROR, [in call to `closure:taint:1.call`,source of the taint here: value returned from `taint::source` with kind `Simple`,return from call to `closure:taint:1.call`,when calling `closure:taint:0.call` here,flows to this sink: value passed as argument `#1` to `taint::sink` with kind `Simple`], source: taint::source, sink: taint::sink, tainted expression: UNKNOWN diff --git a/infer/tests/codetoanalyze/python/pulse/level0.py b/infer/tests/codetoanalyze/python/pulse/level0.py index a894ede05a..77eca2a74b 100644 --- a/infer/tests/codetoanalyze/python/pulse/level0.py +++ b/infer/tests/codetoanalyze/python/pulse/level0.py @@ -3,25 +3,21 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -def taint_sink(x): - pass +import random +import taint -def taint_source(): - pass - -def no_taint_source(): - pass +untained = random.random() # bad -taint_sink(taint_source()) +taint.sink(taint.source()) # ok -taint_sink(no_taint_source()) +taint.sink(random.random()) -tuple = (taint_source(), 0) +tuple = (taint.source(), random()) # bad -taint_sink(tuple[0]) +taint.sink(tuple[0]) # ok -taint_sink(tuple[1]) +taint.sink(tuple[1]) diff --git a/infer/tests/codetoanalyze/python/pulse/level1.py b/infer/tests/codetoanalyze/python/pulse/level1.py index 8d28ba6cee..b8a5751ab7 100644 --- a/infer/tests/codetoanalyze/python/pulse/level1.py +++ b/infer/tests/codetoanalyze/python/pulse/level1.py @@ -3,52 +3,59 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. +import random +import taint -def taint_source() ->int: - return 42 - -def taint_sink(args) -> None: - pass def basic_flow_bad() -> None: - tainted = taint_source() - taint_sink(tainted) + tainted = taint.source() + taint.sink(tainted) + def basic_flow_ok(untainted: int) -> None: - taint_sink(untainted) + taint.sink(untainted) + def fst(x: int, y: int) -> int: return x + def call_fst_bad(untainted) -> None: - arg = fst(taint_source(), untainted) - taint_sink(arg) + arg = fst(taint.source(), untainted) + taint.sink(arg) + def call_fst_ok(untainted) -> None: - arg = fst(untainted, taint_source()) - taint_sink(arg) + arg = fst(untainted, taint.source()) + taint.sink(arg) + def sink_fst_arg(x, y) -> None: - taint_sink(x) + taint.sink(x) + def call_sink_fst_arg_bad(untainted) -> None: - sink_fst_arg(taint_source(), untainted) + sink_fst_arg(taint.source(), untainted) + def call_sink_fst_arg_ok(untainted) -> None: - sink_fst_arg(untainted, taint_source()) + sink_fst_arg(untainted, taint.source()) + def call_taint_sink_on_global_bad1(): global g - taint_sink(g) + taint.sink(g) + def call_taint_sink_on_global_ok(): global g - taint_sink(g) + taint.sink(g) + def call_taint_sink_on_global_bad2(): global g - g = taint_source() - taint_sink(g) + g = taint.source() + taint.sink(g) # we need to call these functions in order to activate specialization basic_flow_bad() @@ -57,7 +64,7 @@ def call_taint_sink_on_global_bad2(): call_fst_ok(0) call_sink_fst_arg_bad(0) call_sink_fst_arg_ok(0) -g = taint_source() +g = taint.source() call_taint_sink_on_global_bad1() g = 0 call_taint_sink_on_global_ok() diff --git a/infer/tests/codetoanalyze/python/pulse/simple-import.py b/infer/tests/codetoanalyze/python/pulse/simple-import.py index 4f7caca865..7e9f5f6a1b 100644 --- a/infer/tests/codetoanalyze/python/pulse/simple-import.py +++ b/infer/tests/codetoanalyze/python/pulse/simple-import.py @@ -3,15 +3,15 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -import level1 -from level1 import taint_sink +import taint +from taint import sink def basic_flow_bad() -> None: - tainted = level1.taint_source() - taint_sink(tainted) + tainted = taint.source() + sink(tainted) def basic_flow_ok(untainted: int) -> None: - level1.taint_sink(untainted) + sink(untainted) basic_flow_bad() basic_flow_ok(0) diff --git a/infer/tests/codetoanalyze/python/pulse/taint.py b/infer/tests/codetoanalyze/python/pulse/taint.py new file mode 100644 index 0000000000..81afe300bc --- /dev/null +++ b/infer/tests/codetoanalyze/python/pulse/taint.py @@ -0,0 +1,10 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +def sink(x): + pass + +def source(): + pass