Skip to content

FlowDroid AliasProblem null abstraction injection causes NPE killing taint analysis #883

Description

@JLEnoch1

Problem

When analyzing certain Android APKs, the return flow function of AliasProblem in FlowDroid 2.15.1 crashes with a NullPointerException, terminating the entire taint analysis and returning zero results.
NPE is non-deterministic — depends on concurrent worker thread scheduling. May require multiple runs to trigger.

Symptoms

Log before crash

[FlowDroid] WARN AccessPathFactory - Primitive types cannot have fields:
baseType=long fields=[<java.lang.Long: long value>]
(repeated 19-151 times depending on configuration)

Stack trace

java.lang.NullPointerException: Cannot invoke
"...FastSolverLinkedNode.getPathLength()" because "targetVal" is null
at IFDSSolver.propagate(IFDSSolver.java:629)
at InfoflowSolver.processEdge(InfoflowSolver.java:62)
at AliasProblem$1$3.computeTargets(AliasProblem.java:725)
at InfoflowSolver.computeReturnFlowFunction(InfoflowSolver.java:95)
at IFDSSolver.processExit(IFDSSolver.java:482)

Root Cause

AliasProblem.java line 712-727: the "two caller args same value" branch in the return flow function calls processEdge(new PathEdge<>(d1, exitStmt, aliasAbs)) without checking if aliasAbs is null.

The null originates from AccessPathFactory.copyWithNewValue() which can return null via 3 paths:

The same function's normal parameter mapping path (line 702-709) has an if (abs != null) check. The duplicate-args branch omits it — this is the definitive code defect.

Additionally, paramLocals[argIndex] uses a caller-side index to access a callee-side array. This only works correctly for IdentityCallerCalleeMapper. For VirtualEdgeTargetCallerCalleeMapper, the index
should be mapped via mapper.getCalleeIndexOfCallerParameter(). (Diagnostic run on BeautyBox shows 16928 entries all using IdentityMapper, so this is a latent bug for other APKs.)

Impact

  • NPE kills the entire taint analysis → zero results
  • 39-151 copyWithNewValue null returns per run (depends on --implicit configuration)
  • Affects any APK where the alias solver hits the duplicate-args branch with incompatible types

Proposed Fix

  1. Map callerArgIndex → calleeArgIndex via mapper.getCalleeIndexOfCallerParameter()
  2. Skip invalid indices (UNKNOWN, ALL_PARAMS, BASE_OBJECT, out-of-bounds)
  3. Skip primitive parameters (no reference aliasing semantics)
  4. Add aliasAp == null → continue (covers all copyWithNewValue null paths)
  5. Add aliasAbs != null → processEdge (covers deriveNewAbstraction null paths)

Also fixes BackwardsAliasProblem with the same paramLocals[i] bug, and a loop variable j/i typo in the ALL_PARAMS branch.

Workaround

The existing IFDSSolver.propagate() null guard (line 624, AIPK-modified) catches null targetVal before getPathLength(). Original FlowDroid 2.15.1 only checks null inside the memoryManager != null
branch, so NPE occurs when memoryManager is null.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions