\documentclass[11pt]{article}
\usepackage{ifthen}
\usepackage{alltt}
% \usepackage{indentfirst}
\usepackage{latexsym}
\usepackage[pdftex]{graphicx}
\usepackage{gdefs}
% \usepackage{logdef}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{setspace}
\usepackage{rotating}
\usepackage{longtable}
\usepackage{hhline}
\usepackage{refs}
\usepackage{graph}
\usepackage{changebar}
\usepackage{array}
\usepackage{wrapfig}
\usepackage[small,compact]{titlesec}

\usepackage{tweaklist}
% this sets the spacings in the itemize environment
\renewcommand{\itemhook}{\setlength{\topsep}{0pt}%
  \setlength{\itemsep}{0pt}%
  \setlength{\parsep}{0ex}%
}

% this sets the spacings in the enumerate environment
\renewcommand{\enumhook}{\setlength{\topsep}{0pt}%
  \setlength{\itemsep}{0pt}%
  \setlength{\parsep}{0ex}%
}

% this sets the spacings in the description environment
\renewcommand{\descripthook}{\setlength{\topsep}{0pt}%
  \setlength{\itemsep}{0pt}%
  \setlength{\parsep}{0ex}%
}

\setlength{\topmargin}{0.0in}
\setlength{\headheight}{0.0in}
\setlength{\headsep}{0.0in}
\setlength{\textwidth}{6.5in}
\setlength{\oddsidemargin}{0.0in}
\setlength{\evensidemargin}{0.0in}
\setlength{\textheight}{9.0in}

\setcounter{topnumber}{5}
\def\topfraction{0.99}
\def\textfraction{0.05}
\def\floatpagefraction{0.9}
\setcounter{bottomnumber}{5}
\def\bottomfraction{0.99}
\setcounter{totalnumber}{10}
\def\dbltopfraction{0.99}
\def\dblfloatpagefraction{0.8}
\setcounter{dbltopnumber}{5}

\setlength{\marginparwidth}{.95in}
\let\oldmarginpar\marginpar
\renewcommand\marginpar[1]{\-\oldmarginpar[\raggedleft\footnotesize #1]%
{\raggedright\footnotesize #1}}

\let\oldthebibliography=\thebibliography
  \let\endoldthebibliography=\endthebibliography
  \renewenvironment{thebibliography}[1]{%
    \begin{oldthebibliography}{#1}%
      \setlength{\parskip}{0ex}%
      \setlength{\itemsep}{0ex}%
  }%
  {%
    \end{oldthebibliography}%
  }

\title{Interprocedural Dataflow Analysis, Part IV: Field Sensitive Dataflow Analysis by Abstracting Access-Paths \\
       CS701 \\
}

\author{Thomas Reps \\ \small[Based on notes taken by Andrew Mironovich on November 19, 2015]}
\date{}

\begin{document}           % End of preamble and beginning of text.

\maketitle
\begin{abstract}
In this lecture, we summarize the application of dataflow-analysis to fields as discussed in Lerch et al.
\cite{ASE:LSBM15}, which extends the IFDS framework \cite{POPL:RHS95} by introducing a technique to abstract the access-path to a field from a base variable. The goal is to conduct a taint analysis to determine which fields a tainted value can propagate to.
\end{abstract}

\section{Dataflow-Analysis for Fields}
There are two approaches to modeling fields for dataflow-analysis: "field-based" models and "field-sensitive" models. 

Field-based models treat fields declared in the program similarly to local variables. However, this introduces a possible source of imprecision. For example:

\[
  \begin{array}{l}
    a.f = source() \\
    c = b.f \\
    sink(c)
  \end{array}
\]

The above source code snippet will produce a false positive with a field-based analysis, which would indicate that the variable $c$ could contain a tainted value from $source()$, while really $c$ cannot contain a tainted value from source because it was assigned from $b.f$, not $a.f$.

A field-sensitive analysis will consider a field in light of its base variable \emph{and} its access path. In the above code snippet, $c$ will not be considered tainted, since it was assigned from the field $f$ from a different base variable. The problem with field-sensitive modeling is that the access path for a field may be arbitrarily long. For example, in a doubly-linked list, the next node could be accessed with $node.next$, $node.next.prev.next$, etc. 

This problem can be solved with $k-limiting$ - artificially limiting the the length of field accesses sequences to some maximum. Unfortunately, limiting the number of field accesses reduces precision and makes static analysis more difficult. Further, even analyses using small values of $k$ are at risk of running out of memory.

\section{Access-Path Abstraction}
One of the goals of the access-path abstraction approach is to not re-analyze a call to a procedure if a previous call to the procedure was made with a compatible access path. Instead, our goal is to already have information about the previous call was made to the procedure.

% Insert figure 1

In a language without destructive updating, this task can be turned into a CFL reachability problem. To use the $car$/$cdr$ example, each time we see $car$ is like seeing an open-parenthesis, and each time we see $cdr$ is like seeing a close-parenthesis; then we just need to check the order of parentheses to make sure we have a valid path.

% Insert figure 2

In a procedure based language, this task is more difficult. Even paths which have $car$ and $cdr$ in the right order may not be valid, because procedure calls must be accounted for as well.

% Insert figure 3

In the above example, the pattern of parenthesis is "([)]"; since the
parentheses are interleaved, this is not a valid path. Unfortunately,
this problem is undecidable, due to Post's Correspondence Problem
\cite{TOPLAS:Reps00}.

Lerch et al. encodes similar fields together into sets of access paths. An \textbf{\emph{access path}} is a local variable followed by a sequence of field accesses $\alpha$ = ($\alpha_1$, \ldots, $\alpha_n$), where $\alpha_1$ is a local variable and $\alpha_i$ is a field for $2 \le i \le n$. An \textbf{\emph{access-path bundle}}, $\langle\langle\alpha, E\rangle\rangle$ is a tuple containing an access path $\alpha$ and an exclusion set $E$. The \textbf{\emph{exclusion set}} represents a set of fields which the access path may not immediately precede. The access bundle as a whole represents the field access paths with length greater than or equal to $|\alpha|$, that begin with the sequence $\alpha$, and, if the length of of the total access path is greater than $|\alpha|$, whose field $x_{|\alpha|+1}$ is not in $E$.

Access-path bundles can be partially ordered. $\langle\langle\alpha, E_\alpha\rangle\rangle \supseteq \langle\langle\beta, E_\beta\rangle\rangle$ holds iff:
\begin{enumerate}
 \item
  $|\alpha| \le |\beta|$
 \item
  $\alpha_i = \beta_i, \; 1 \le i \le |\alpha|$
 \item
  $\beta_{\alpha+1} \notin E_\beta, \; if \: |\alpha| \le |\beta|$
 \item
  $E_\alpha \subseteq E_\beta, \; if \: |\alpha| = |\beta|$
\end{enumerate}

If two access-path bundles differ only in their exclusions, then $\langle\langle\alpha, E_\alpha\rangle\rangle \approx \langle\langle\beta, E_\beta\rangle\rangle$, which means:
\begin{enumerate}
 \item
  $|\alpha| = |\beta|$
 \item
  $\alpha_i = \beta_i, \; 1 \le i \le |\alpha| = |\beta|$
\end{enumerate}

For two access bundles, $\tilde\alpha$ and $\tilde\beta$, then if $\tilde\alpha \approx \tilde\beta$ or $\tilde\alpha \supseteq \tilde\beta$, then their \emph{delta}, $\triangle(\tilde\alpha, \tilde\beta)$, is defined as:

\[
  \begin{array}{@{\hspace{0ex}}|@{\hspace{.5ex}}l@{\hspace{.5ex}}|@{\hspace{0ex}}}
    \hline
    \triangle(\tilde\alpha, \tilde\beta) :=
    \left\{\begin{array}{@{\hspace{0ex}}c@{\hspace{2.0ex}}l@{\hspace{0ex}}}
      ((\beta_{|\alpha|+1},\cdots, \beta_{|\beta|}), E_\beta) & \textrm{if}~|\alpha| < |\beta|  \\
      (\epsilon, E_\alpha \bigcup E_\beta) & \textrm{if}~|\alpha| = |\beta| \\
          \end{array}\right. \\
    \hline
  \end{array}
\]

An access-path bundle and a delta $\triangle = (\delta, E_\delta)$ can be concatenated together to produce a new access-path bundle:
\[
  \begin{array}{@{\hspace{0ex}}|@{\hspace{.5ex}}l@{\hspace{.5ex}}|@{\hspace{0ex}}}
    \hline
    \tilde\alpha::\triangle :=
    \left\{\begin{array}{@{\hspace{0ex}}c@{\hspace{2.0ex}}l@{\hspace{0ex}}}
      \bot & \textrm{if}~\delta_1 \in E_\alpha \\
      \langle\langle\alpha_1, \cdots, \alpha_{|\alpha|}, E_\alpha \bigcup E_\delta\rangle\rangle & \textrm{if}~\delta = \epsilon  \\
      \langle\langle\alpha_1, \cdots, \alpha_{|\alpha|}, \delta_1, \cdots, \delta_{|\delta|}\rangle\rangle & \textrm{if}~\delta \neq \epsilon \\
          \end{array}\right. \\
    \hline
  \end{array}
\]

% Insert figure 4

The motivation behind creating the access-path abstraction is to be able to use information from other calls to a procedure to determine if a tainted value will propagate. In the above figure, the procedure Q is called from both procedures P and R. If the call from P to Q is analyzed first, then we would like to be able to reuse the information computed for this call when the call from R to Q is analyzed. The access-path bundles of calls to Q are recorded at the abstraction point at the entry point to Q, $d_3$. If $d_3 \supseteq d_2$, then $d_4::\triangle(d_3, d_2)$. This means that the summary transformation from $d_3$ to $d_4$ is applicable to the incoming information in $d_2$, and can be computed by taking the delta between $d_3$ and $d_2$ and concatenating it to $d_4$.

When an access-path bundle is passed to a procedure during the data-flow analysis, the analysis uses an abstracted version of the bundle's access path containing only the first variable (the name of the local variable object). If a field in the object is read from, the analysis needs a way to determine if that field contains a tainted value. This information is computed on-the-fly when needed by checking the other callers of the procedure - if another caller of the procedure indicated that the field contained a tainted value, then the field is known to be tainted. If no other caller of the procedure has yet requested an analysis for the field in question, then the analysis creates a callback which will be invoked if and when another caller requests an analysis and passes in the access-path to that field.

In the following example, the procedure is analyzed with respect to several callers. The procedure has previously been provided with the information that $a.f.g$ is (or is not) tainted, and it has been determined if $a.f.g.h$ is (or is not) tainted through a data-flow analysis. We have the field $b.p.q$ and would like to determine if $b.p.q.h$ will be tainted after the procedure is called. However, we do not need to re-do the full data-flow analysis within the procedure to make this determination, since the results will be analogous to the result we already know for $a.f.g.h$.

% Insert figure 5

\section{Summary}

The approach proposed in Lerch et al. allows for more precise data-flow analysis of fields using field-sensitive modeling. In addition, using the access-path abstraction means we can avoid using $k$-limiting, which will improve accuracy and performance. Previous field-sensitive analyses attempted on the Java Class Library were unable to complete before running out of memory; however, by using the access-path abstraction Lerch et al. were able to complete a field-sensitive analysis on the whole Java Class Library. The access-path abstraction approach scales better and is at least as precise as other field-sensitive analyses.

{\small
  \bibliography{cs701}
  \bibliographystyle{plain}
}

\end{document}
