secure-software-engineering / FlowDroid

FlowDroid Static Data Flow Tracker
GNU Lesser General Public License v2.1
1.02k stars 292 forks source link

Non-deterministic behavior of the command line tool #735

Open draftyfrog opened 1 month ago

draftyfrog commented 1 month ago

Hi,

I've found nondeterministic behavior in the FlowDroid command line tool.

I'm running the command line tool with the following settings:

java -jar ./soot-infoflow-cmd-jar-with-dependencies.jar -a {path-to-apk} -s {path-to-SourcesAndSinks.xml} -o ./out.xml -cp -on -pr PRECISE -ps -d -ol -p {path-to-platforms-folder}

Running it multiple times on the same APK doesn't always output the leak in s_sink10() (annotated in code example below) - but other leaks along the path are always found just as expected.

I'm using FlowDroid release 2.12 on an APK compiled with android build tools 8.3.2. The App consists of only one file MainActivity.java:

MainActivity

```java import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String var2 = ""; var2 = "exxeeygukh"; var2 = "glocleapyj"; s_sink0(var2); var2 = "dwwibdszyk"; var2 = source(); var2 = var2; var2 = "oeajaxfshb"; if ("" + Math.random() == "mpqforbmjx") { var2 = "juxpnzxgtc"; s_sink1(var2); s_sink3(var2); var2 = "qijpmrqscx"; var2 = source(); s_sink5(var2); s_sink12(var2); var2 = source(); } else { var2 = "zdxibfnlvf"; var2 = var2; String var18 = ""; var18 = source(); String var28 = ""; s_sink8(var2); int var59 = 0; var2 = var28; var18 = source(); var18 = source(); var28 = source(); } var2 = source(); // Taint path starts here var2 = var2; int var17 = 0; s_sink2(var2); // This sink is always found as leak s_sink4(var2); // This sink is always found as leak var2 = var2; s_sink6(var2); // This sink is always found as leak int var29 = 0; var17 = -29; if ((int) (Math.random() * 10000) > -88) { String var41 = ""; var17 = -51; } else { s_sink7(var2); var2 = source(); String var46 = ""; var2 = "yeekgsdyyb"; var2 = source(); s_sink14(var2); var46 = source(); var29 = -22; } var29 = 86; int var35 = 0; s_sink9(var2); // This sink is always found as leak var17 = -72; s_sink10(var2); // This leak sometimes gets found and sometimes doesn't if ((int) (Math.random() * 10000) < var17) { var35 = var35; var2 = source(); } else { s_sink24(var2); var35 = var29; String var197 = ""; } var17 = 7; var17 = -67; if ("" + Math.random() == "qsspofpxnc") { var29 = var17; s_sink15(var2); var35 = var17; var17 = -53; s_sink28(var2); } else { int var82 = 0; s_sink20(var2); s_sink23(var2); var29 = 47; var2 = "qgrusikqnj"; int var159 = 0; var2 = source(); } int var45 = 0; var29 = -60; if ("" + Math.random() == var2) { s_sink13(var2); var2 = var2; var45 = var29; } else { int var50 = 0; s_sink22(var2); var35 = var29; } var45 = -70; int var51 = 0; if ("" + Math.random() == var2) { var35 = -35; } else { int var84 = 0; var17 = 16; String var117 = ""; String var212 = ""; } s_sink11(var2); var45 = 7; if ((int) (Math.random() * 10000) == var29) { var2 = var2; var2 = source(); } else { var35 = 40; s_sink19(var2); var45 = 56; } if ("" + Math.random() == var2) { } else { s_sink16(var2); var35 = -12; } int var69 = 0; String var71 = ""; if ("" + Math.random() == "uzdusgstsg") { var29 = 18; } else { var29 = 91; var2 = source(); } s_sink17(var2); String var78 = ""; if ("" + Math.random() == var78) { String var125 = ""; } else { var2 = var78; var51 = 6; } if ("" + Math.random() == "maajfvfbnq") { } else { var78 = source(); } String replace4913427 = "UNUSED"; var71 = "wayawdjzrj"; s_sink18(var2); if ((int) (Math.random() * 10000) < 4) { } else { var2 = var2; s_sink30(var2); } if ((int) (Math.random() * 10000) == 1) { var51 = -64; } else { String var102 = ""; s_sink29(var2); var71 = "xzkvbtwsgc"; s_sink32(var2); s_sink43(var102); } var17 = -12; var35 = var69; if ((int) (Math.random() * 10000) > var29) { String var124 = ""; } else { int var151 = 0; var35 = -60; s_sink35(var71); } String var104 = ""; var17 = 17; var29 = var69; s_sink21(var2); var78 = var104; String replace4913476 = "UNUSED"; var104 = source(); var2 = var71; if ((int) (Math.random() * 10000) == var35) { } else { } if ("" + Math.random() == var104) { } else { var51 = -23; } var17 = var35; var78 = var104; var104 = source(); if ((int) (Math.random() * 10000) < var17) { s_sink31(var104); } else { int var158 = 0; var104 = var104; int var186 = 0; } var69 = var29; int var129 = 0; var45 = -26; String var133 = ""; var78 = source(); String replace4913529 = "UNUSED"; var104 = var104; if ("" + Math.random() == var2) { } else { s_sink27(var71); } String var139 = ""; var104 = var78; var104 = var133; String var142 = ""; String replace4913542 = "UNUSED"; s_sink25(var104); int var146 = 0; int var147 = 0; s_sink26(var104); var69 = var147; if ((int) (Math.random() * 10000) == var129) { var78 = "wsmbothcpw"; s_sink40(var2); } else { var142 = source(); } var2 = "qzhbjdojzp"; if ((int) (Math.random() * 10000) > var146) { var139 = source(); } else { } var78 = var142; String replace4913570 = "UNUSED"; var51 = 75; var104 = "jzxrhlabjm"; int var169 = 0; if ((int) (Math.random() * 10000) == var147) { } else { } if ("" + Math.random() == var71) { var69 = -32; } else { } var2 = source(); if ("" + Math.random() == "deebpmmuqb") { } else { var78 = source(); } var35 = 25; if ("" + Math.random() == "rexwgdkqoe") { var51 = -61; } else { int var198 = 0; } if ("" + Math.random() == "ckyyqgcryg") { } else { } if ("" + Math.random() == var71) { } else { } if ((int) (Math.random() * 10000) > -70) { String var238 = ""; } else { } String var184 = ""; String replace4913638 = "UNUSED"; if ((int) (Math.random() * 10000) < 48) { var71 = source(); var17 = -28; } else { String var236 = ""; } var169 = -3; if ("" + Math.random() == "oqwkqrdjib") { } else { var78 = source(); } var2 = "wajwmzrhtx"; var133 = "lqudomgfyp"; var78 = source(); var104 = "gbkucfpelb"; String replace4913673 = "UNUSED"; if ("" + Math.random() == "nzfrohsrdd") { } else { } if ((int) (Math.random() * 10000) == -69) { var35 = 19; var104 = source(); } else { } if ("" + Math.random() == "uhdaqemsjq") { } else { var129 = var147; } String replace4913687 = "UNUSED"; s_sink33(var71); s_sink34(var104); int var214 = 0; var129 = 25; int var219 = 0; String replace4913711 = "UNUSED"; var142 = source(); String replace4913719 = "UNUSED"; var71 = var71; String var227 = ""; if ("" + Math.random() == var133) { } else { } if ("" + Math.random() == var227) { } else { } s_sink38(var184); var227 = source(); var133 = source(); if ("" + Math.random() == "ykchsqkpcd") { } else { } var227 = var133; s_sink39(var133); if ("" + Math.random() == "ynakvpmliq") { } else { } if ((int) (Math.random() * 10000) < var69) { } else { } s_sink41(var184); if ("" + Math.random() == "jzksngtmar") { } else { } if ((int) (Math.random() * 10000) > var214) { } else { } s_sink42(var104); if ((int) (Math.random() * 10000) == var45) { } else { } if ("" + Math.random() == "vqegfkbeuh") { } else { } } public String source() { return "Hello"; } public void sink(String param) { } public void s_sink0(String param) { } public void s_sink1(String param) { } public void s_sink2(String param) { } public void s_sink3(String param) { } public void s_sink4(String param) { } public void s_sink5(String param) { } public void s_sink6(String param) { } public void s_sink7(String param) { } public void s_sink8(String param) { } public void s_sink9(String param) { } public void s_sink10(String param) { } public void s_sink11(String param) { } public void s_sink12(String param) { } public void s_sink13(String param) { } public void s_sink14(String param) { } public void s_sink15(String param) { } public void s_sink16(String param) { } public void s_sink17(String param) { } public void s_sink18(String param) { } public void s_sink19(String param) { } public void s_sink20(String param) { } public void s_sink21(String param) { } public void s_sink22(String param) { } public void s_sink23(String param) { } public void s_sink24(String param) { } public void s_sink25(String param) { } public void s_sink26(String param) { } public void s_sink27(String param) { } public void s_sink28(String param) { } public void s_sink29(String param) { } public void s_sink30(String param) { } public void s_sink31(String param) { } public void s_sink32(String param) { } public void s_sink33(String param) { } public void s_sink34(String param) { } public void s_sink35(String param) { } public void s_sink36(String param) { } public void s_sink37(String param) { } public void s_sink38(String param) { } public void s_sink39(String param) { } public void s_sink40(String param) { } public void s_sink41(String param) { } public void s_sink42(String param) { } public void s_sink43(String param) { } } ```

My SourcesAndSinks.xml specifies the function java.lang.String source() as source and all the functions void s_sink[id](java.lang.String) as sinks.