Download A static secure flow analyzer for a subset of Java 1998-03-01

Document related concepts
no text concepts found
Transcript
Calhoun: The NPS Institutional Archive
Theses and Dissertations
Thesis and Dissertation Collection
1998-03-01
A static secure flow analyzer for a subset of Java
Harvey, James D.
Monterey, California. Naval Postgraduate School
http://hdl.handle.net/10945/9008
DUDLEY KNOX LIBRARY
NAVAL POSTGRADUATE SCHOOL
MONTEREY CA 93943-5101
NAVAL POSTGRADUATE SCHOOL
Monterey, California
THESIS
A STATIC SECURE FLOW
ANALYZER FOR A
SUBSET OF JAVA
by
James D. Harvey
March, 1998
Thesis Advisor:
Dennis M. Volpano
Second Reader:
Craig
Approved
for public release; distribution
W. Rasmussen
is
unlimited.
MONTEREY CA
93943-biu
REPORT DOCUMENTATION PAGE
Public reporting burden for this collection of information
estimated to average
Form Approved
OMB No.
0704-0188
hour per response, including the time for reviewing instruction, searching
existing data sources, gathering and maintaining the data needed, and completing and reviewing the collection of information. Send comments regarding
this burden estimate or any other aspect of this collection of information, including suggestions for reducing this burden, to Washington headquarters
Services, Directorate for Information Operations and Reports, 1215 Jefferson Davis Highway, Suite 1204, Arlington, VA 22202-4302, and to the Office of
Management and Budget, Paperwork Reduction Project (0704-0188) Washington DC 20503.
1.
4.
AGENCY USE ONLY
TITLE
is
1
REPORT DATE
March 1998
(Leave blank)
2.
3.
REPORT TYPE AND DATES COVERED
Master's Thesis
AND SUBTITLE
5.
FUNDING NUMBERS
8.
PERFORMING
A STATIC SECURE FLOW ANALYZER FOR A SUBSET OF JAVA
AUTHOR(S)
Harvey James D.
6.
7.
PERFORMING ORGANIZATION NAME(S) AND ADDRESS(ES)
ORGANIZATION REPORT
Naval Postgraduate School
Monterey, CA 93943-5000
9.
NUMBER
SPONSORING MONITORING AGENCY NAME(S) AND ADDRESS(ES)
10. SPONSORING
MONITORING
/
/
AGENCY REPORT NUMBER
11.
SUPPLEMENTARY NOTES
The views expressed
in this thesis are
those of the author and do not reflect the official policy or position of the Department of
Defense or the U.S. Government.
12a.
DISTRIBUTION / AVAILABILITY STATEMENT
Approved
13.
12b.
DISTRIBUTION
CODE
for public release; distribution is unlimited.
ABSTRACT (maximum 200
words)
As the number of computers and computer systems in existence has grown over the past few decades,
we have come to depend on them to maintain the security of private or sensitive information. The execution
of a program may cause leaks of private or sensitive information from the computer. Static secure flow
analysis
an attempt to detect these leaks prior to program execution.
is
It is
approach
is
We
possible to analyze programs by hand, but this
to automate the analysis, which
describe
secure flow analyzer
1.0.2, using
grammar
14.
is
what
is
often impractical for large programs.
presented.
It
better
this thesis explores.
some previous research and give background information about secure flow
is
A
analysis.
A
implements a secure flow type inference algorithm, for a subset of Java
a parser generator called Java Compiler Compiler (JavaCC). Semantic actions are inserted into a
specification to
perform the secure flow analysis on a given program.
SUBJECT TERMS
15.
Secure Flow Analysis, Type Inference, Program Certification, Information Flow, Protection
NUMBER OF
PAGES
98
17.
SECURITY CLASSIFICATION OF
REPORT
Unclassified
NSN
7540-01-280-5500
18.
SECURITY CLASSIFICATION OF
THIS PAGE
Unclassified
19.
SECURITY CLASSIFI- CATION
OF ABSTRACT
Unclassified
16.
PRICE CODE
20.
LIMITATION
OF ABSTRACT
UL
Standard Form 298 (Rev. 2-89)
Prescribed by ANSI Std. 239-18
u
Approved
for public release; distribution
is
unlimited
A STATIC SECURE FLOW ANALYZER FOR A SUBSET OF JAVA
James D. Harvey
Lieutenant, United States
B.S.,
The Ohio State
Submitted
Navy
University, 1990
in partial fulfillment
of the
requirements for the degree of
MASTER OF SCIENCE IN COMPUTER SCIENCE
from the
NAVAL POSTGRADUATE SCHOOL
March 1998
DUDLEY KNOX LIBRARY
NAVAL POSTGRADUATE SCHOOL
MONTEREY CA
93943-5101
ABSTRACT
As
the
number of computers and computer systems
the past few decades,
we have come
from the computer.
detect these leaks prior to
It is
programs.
depend on them
to maintain the security
Static secure
better
of private
leaks of private or
flow analysis
is
an attempt
to
program execution.
possible to analyze programs by hand, but this
A
grown over
existence has
The execution of a program may cause
or sensitive information.
sensitive information
to
in
approach
is
to
is
often impractical for large
automate the analysis; which
is
what
this thesis
explores.
We
describe
secure flow analysis.
some previous research and
A
secure flow analyzer
type inference algorithm, for a subset of Java
is
1
give background information about
presented.
.0.2,
implements a secure flow
using a parser generator called Java
Compiler Compiler (JavaCC). Semantic actions are inserted
to perform the secure flow analysis
It
on a given program.
into a
grammar
specification
VI
TABLE OF CONTENTS
I.
INTRODUCTION.
1
A.
SECURE INFORMATION FLOW
B.
A TYPE BASED TREATMENT OF SECURE INFORMATION
1
FLOW..
2
C.
A TYPE INFERENCE ALGORITHM
2
D.
AN APPLICATION OF THE ALGORITHM
E.
THESIS ORGANIZATION
.3
4
II.
THE LATTICE MODEL OF SECURE INFORMATION FLOW
III.
A SECURE FLOW TYPE SYSTEM
IV.
A SECURE FLOW TYPE INFERENCE ALGORITHM
1
V.
IMPLEMENTATION OF THE TYPE INFERENCE ALGORITHM
1
A.
BASIC DESCRIPTION OF A JAVACC
SPECIFICATION
.5
7
GRAMMAR
15
B.
IMPLEMENTING THE ALGORITHM USING JAVACC
17
C.
RESTRICTIONS IMPOSED ON PROGRAMS.
24
VI.
AN EXAMPLE RUN OF THE STATIC ANALYZER
27
VII.
CONCLUSIONS
29
LIST OF REFFERENCES
31
APPENDIX
A.
JAVA
GRAMMAR SPECIFICATION..
33
APPENDIX
B.
STATIC ANALYZER SOURCE CODE
67
APPENDIX
C.
TEST PROGRAMS
79
INITIAL DISTRIBUTION LIST
85
VI
Vlll
LIST
OF FIGURES
Core Language
1
Figure 2
Volpano-Smith Type Inference Algorithm
12
Figure 3
Example Program
13
Figure 4
Algorithm Results of Sample program
14
Figure 5
Algorithm Results
Figure 6
Principle
Figure 7
Sample Productions
Figure 8
Assignment Production
Figure 9
Java Specification Productions to Handle Local Variable
Figure
1
Type
after
after
Type Simplification
14
Applying Monotonicity-Based Instantiations
16
._
21
22
Declarations
Figure 10
Specification Changes for letvar Statement
Figure
Static
1
Figure 12
Analyzer Test Program
Test Program Results
14
_
24
27
27
_
IX
ACKNOWLEDGEMENT
To
Dr. Dennis Volpano,
would
I
like to express
my
patient while repeatedly explaining the required concepts.
knowledge, instruction and
being able to complete
To
ability to explain difficult
deepest thanks for being so
Your
support, guidance,
concepts was instrumental to
my
this thesis.
Dr. Craig Rasmussen,
I
support, guidance, and dedication.
would
Your
like to express
my
attention to detail
sincere gratitude for your
was
essential through this
process.
To my
wife, Cindy, and daughter, Madison,
nights and missed dinners.
I
who have
cheerfully put up with late
thank you for your support, understanding and devotion.
\i
Xll
I.
INTRODUCTION
The number of computers and computer networks has exploded over the past few
decades, and computer security
is
a major concern. In a multi-level system where
information exists with different security classifications, such as a military computer
system,
to
we want
to protect information with a high security classification.
have an automated tool to detect whether information
applications remains secret and
statically
is
we wish
to
It is
desirable
keep secret
in
not leaked. This thesis introduces a program that will
analyze a subset of Java programs to ensure that private information
is
not
leaked.
SECURE INFORMATION FLOW
A.
Verifying secure information flow within computer systems
flow occurs from a storage object x to another storage object y
when
information stored in x
to y.
A
flow
may
necessary in order
Denning and Denning
to protect sensitive information, especially in a military system.
state that information
is
is
transferred to y, or used to derive information transferred
be either explicit or implicit
Explicit information flow occurs
when
[1].
information
is
directly copied or
transferred from one storage object to another. Consider the code segment "y := x".
information contained in x
The flow from x
to
y
is
is
directly
copied into
y,
so information flows from x to
independent of the value stored
Implicit flow occurs
when information
is
The
y.
in x.
indirectly copied or transferred
storage object to another. If the variable x contains either
or
1,
from one
then the following code
segment
will
copy the value of x
y:=0;
In this case, there
is
allowed only
(x
=
must
then y
1)
y.
of y
:=
1
However, the value of x determines
be executed. The flow
will
if the security classification
classified high then y
B.
if
no direct flow from x to
whether the then statement
an implicit flow:
into y using
in
both of these examples
is at least that
of x. For instance,
also be classified high in order for the
code
if
is
x were
to be secure [1].
A TYPE-BASED TREATMENT OF SECURE INFORMATION FLOW
Goguen and Meseguer introduced a notion of security
systems called noninterference
[2],
The
basic idea
is
that a
for deterministic
system has users
supply information with various security classifications to the system.
the noninterference property if
its
who may
A system satisfies
same when
low-level outputs remain the
computer
its
high-level
inputs are changed.
Volpano and Smith
applied to languages, the idea
changes
C.
in high-level
have applied this idea to programming languages.
[3]
is
program
that low-level
When
program outputs are unaffected by
inputs.
A TYPE INFERENCE ALGORITHM
Volpano and Smith go on to describe an algorithm
that
is
defined by cases on the
phrases of a simple imperative language. The evaluation of an expression returns a
principal type and a set
between two types
low then
x'
<
x
is
of typing
A typing constraint is an inequality
constraints.
that are security levels.
a constraint. Note that
x'
For example,
=
x
is
equivalent to
important to note also that the algorithm produces constraints
where a type variable ranges over types
like
type high and
if x is
x'
< x and
among
x
x'.
type
It is
type variables,
high and low. Constraint-set
2
<
t' is
satisfiability
can be used on the
set
of constraints
program being analyzed,
The
to
determine whether
illegal
flows exist
for instance, if a constraint set contains high
<
in the
low.
which type variables range, depend on the
classifications, or types, over
system being modeled. In a typical military system, the types would be unclassified,
and top
confidential, secret,
secret.
For the purposes of this discussion,
we
consider a
simple system of only two types, high and low, where low < high.
As an example of how the
assignment statement, y :=
variables To and
x.
algorithm works, consider the case of the preceding
Assuming x and y have already been assigned
the type
respectively, the following set of constraints will be generated by the
Tj
type inference algorithm:
{To<T 2
,
Tl = T2, T3
Therefore, the principal type of the expression
simplified to {to
<
ti, 13
<
states that the classification
Ti }.
is 13
<T 2
}
cmd. The constraint
can be
So, for the assignment statement y := x, the algorithm
of y must be
at least as
high as the classification of x. The
second constraint allows downward coercion on command types
D.
set
[7].
AN IMPLEMENTION OF THE ALGORITHM
This thesis presents a Java program that implements the type inference algorithm.
The program
is
generated from a specification that
JavaCC. JavaCC
like
is
distribution.
The
input to a compiler compiler called
a tool that reads a grammar specification written
manner and converts
incorporated into a
is
it
into a parser for the
grammar
in
a
LEX/ YACC-
grammar. The algorithm was
specification for Java 1.0.2 supplied with the
JavaCC
actions specified by the algorithm were performed by adding Java code
3
(semantic actions) to the corresponding productions in the
generated parser
is
grammar
a secure flow analyzer for a subset of Java.
expressions, and other Java functionality
specification.
The
Several statements,
were removed from the grammar specification
because they are not currently supported by the type inference algorithm
E.
THESIS ORGANIZATION
Work
in the
area of secure information flow and a lattice model of secure
information flow are discussed
type system in Chapter
Chapter V, the
static
III.
in
The
Chapter
II,
followed by a description of the secure flow
type- inference algorithm
analyzer and the Java subset
we
is
discussed in Chapter IV. In
consider are discussed. Chapter
gives an example run of the analyzer, and Chapter VII discusses
work and
some
possible future
presents conclusions about secure flow analysis and the static analyzer.
VI
THE LATTICE MODEL OF SECURE INFORMATION FLOW
II.
The
security
mechanisms of most computer systems do not attempt
to detect or
prevent insecure information flows. Computer system security requires that programs at
high security levels be unable to transfer information to low security users or programs.
Most
access control mechanisms are concerned with direct access control and are not
concerned with information flow channels that may
exist.
Other systems rely on the
trustworthiness of processes [5].
In the lattice
<S, ->>
relation.
[5].
S
is
a set of security classes and -^
The flow
Every variable x
model of secure flow, a flow policy
is
allowed
if
in a
x -> y
represented by the poset
a partial order, called the flow
relation specifies permissible flows
assigned a security class, denoted
that can be determined at
y are variables
is
is
between the security
x, that is statically
bound
to x
and
compile time from declarations given in the program. If x and
program and an information flow from x
to
y
flow
exists, then the
is
[6].
Each programming construct has a
certification rule.
Some
rules,
assignment statements, certify explicit flows and other rules, such as
implicit flows.
classes.
An assignment
if
such as
statements, certify
statement, x := y, will be certified if x ->
y.
The
rules for
conditional constructs such as the following if statement certify implicit flows.
if
This statement
is
certified if x -^
If the poset
greatest lower
<S, ~^>
bound
is
a
x=
y and x ->
lattice,
for any pair
then y :=
:=
1
z.
then there
is
a unique least upper bound and
A simple grammar consisting of synthesized
of classes.
attributes can be given to certify programs.
eke z
The
5
attributes are security classes
computed
using the least upper bound, lub, and greatest lower bound, gib, operations. For example,
the certification requirement for the above if statement
x-»glbfcz)[6].
becomes the
single condition
III.
A SECURE FLOW TYPE SYSTEM
Volpano, Irvine, and Smith describe a type system consisting of a
inference rules and axioms for deriving typing judgements.
divided into three levels.
One
level contains data types,
of type
set
The types of the system
which we
These are the security classes of Denning's model and they are
are
refer to as z types.
partially ordered, for
example, low < high.
At the next
types z
cmd and
level, are the
n types. They consist of the data types
t,
command
the procedure types
z proc{z\, i2 var, T3 ace)
A variable of type
z
cmd only
level
if
every assignment
z or higher.
is
of its body. That
is,
types, type t var
this, are
it
can store information
in the
command
Lastly, the z in the
A command
to a variable
whose
has type
security
refers to the security level
final level are the p, or phrase, types.
and type z ace (we ignore type z
ace).
They
consist of are the
So, our procedure types, in this
of the form:
The
partial order
The subtype
relation
subtype of z', then
z'
made
above procedure type
zproc(z\
level
is
at level z.
a call to a procedure of this type would have type z cmd.
At the third and
n
means
z var
t'
is
on
z types
is
var,...,zn var)
extended to a subtype relation over phrase types.
anti-monotonic in the types of the commands, meaning
cmd is
a subtype of z cmd.
The
intuition here
is
that if one
(high) information then they can read level z (low) information. There
7
if z is
a
can read
is
also a
typical type subsumption rule that states if a phrase has type
type
p' if p is
a subtype of p'
The typing
rules
p then
it
can be assigned a
[7].
of the system guarantee secure
explicit
and
implicit flow.
Consider the typing rule for assignment:
1-
7
x
y\- e
y\-
where y
is
z
:
x :=e
:
zcmd
an identifier typing
explicit flow
level.
t var
:
from expression
maps
that
identifiers to
e to variable x
is
secure
p types. The
if e
rule states that the
and x have the same security
This does not prevent e from having a lower security level than
x,
because
subtyping allows the level to be coerced upward.
The next example shows
Consider the following program phrase where x
exists.
x =
if
There
is
no
value of x.
is
a rule that deals with a situation
explicit
then y
1
:=
flow from x
To guarantee
else
1
is
either
where an
or
implicit
flow
1
y :=
to y, but
when
the implicit flow
the phrase
from x to y
is
is
executed, y will contain the
secure, the following typing rule
used:
y
|-
e
:
t
y
|-
c
:
z
y\-
c'
:
cmd
zcmd
y\-ife then c
The commands
known by
c
and
c'
else
c'
:
zcmd
must have type r cmd, because information of type
evaluating the predicate
e.
variables at security level t or higher.
Therefore c and
The
c'
r
is
implicitly
can only make assignments to
rule requires e, c,
and
c'
to
have the same
namely
security level,
t.
Nevertheless, an
upward
from
implicit flow
e to c and
c'
can be
accommodated by subtyping.
There
the
is
also a rule for local variable declarations.
A
local variable declaration
of
form
letvar x := e in c
creates a variable x with an
initial
value
of x may cause an implicit flow, but
Two lemmas
it
is
e,
whose scope
is
command
c.
The
initialization
always harmless.
are needed to prove type soundness: Simple Security and
Confinement. Simple Security applies to expressions and Confinement applies to
commands.
If an expression e
can be assigned type
only variables of type x or lower will be read
Confinement says
that
is
updated
that if a
in c
command
c
e
then Simple Security states that
is
evaluated (no read up).
can be assigned type z cmd, then every variable
has security level t or higher (no write down). These two lemmas are
used to prove that the type system
noninterference property.
is
sound. Soundness
The noninterference property
typed program do not interfere with variables
It is
when
r,
at
is
formulated as a
states that variables in a well-
lower security
possible to automatically check whether a program
techniques of type inference. The basic idea of type inference
represent
levels.
unknown types
inequalities.
in a
is
is
well typed, using the
to use type variables to
program, and to generate constraints
An assignment of types to these
in the
variables must satisfy the constraints in
order for the program to be well typed with respect to that assignment.
can be formulated that represents
all
form of
A principal type
possible types the program can be given.
10
IV.
A
A SECURE FLOW TYPE INFERENCE ALGORITHM
type inference algorithm that ensures secure information flow
this chapter.
is
Volpano and Smith have extended the type system discussed
chapter to a simple language with
first
order procedures
[3].
They
described in
in the
previous
also prove the
noninterference property for the system in order to establish the type soundness in the
context of procedures. Figure
expressions
::=
1
shows the core language they considered.
x
et
n
|
+
|
/
e2
|
proc(in xj, inout x 2 , out X3) c
commands
::=
ci; c 2
if e
|
then
cj else
c2
\
while e do c
\
:=e 2
letvar x
ei
\
:= e in c
\
letproc x (in */, inout x 2 , out X3) c in c'
\
e(e],e 2 ,e 3 )
Figure
1
.
Core Language
For expressions, meta-variable x ranges over
and
/
identifiers,
n ranges over integer
literals,
ranges over locations. Expressions also consist of anonymous procedure
expressions. Their
Commands
names
consist
are provided via letproc.
of the following: composition of commands,
if,
assignment, variable declarations, procedure declarations, and procedure
Volpano and Smith give a secure flow type inference algorithm
in Figure 2
and
is
while loops,
calls.
in [3].
It is
shown
defined by cases on the phrases of the core language. The algorithm
takes as inputs a location typing A, an identifier typing
11
7,
a program phrase p, and a set of
=
rV(A,7,P,V)
i
ca»epof
case t(«) of
:
a^V
r({r<a),c,Vu{c,})
?oar: ({?<«}, a, Vu{«})
default
V
<«^
l:({A(0<a},a,VU{a})
+ ej
g
o*V
»:«},o:,Vu{cf})
ei
or
fail
:
:
let(a,
)
n,,V")=^(A,7,ea ,n
in(CiUCaU{n=ft},T,,f")
proc (in
inout xa, oat u) c
(C.rcmd.V") - W^A.tIx,
xi,
let
in
:
:
a,x 3
var, 6 ace), V")
(C,r proc(a,
:
a,
P
oar, x 3 :* ace],
and
c.VU {«,/?,*})
gV
*
(Ci,n cmd, V) = W{\,y,clt V)
kt (Ca.ft ctmf,r")= W(A,7,Ca, V)
in (Ci UCaU{f\ = ft},ft etnd V")
ex; ca :fct
y
if e
then
else c 3
c\
:
let(C,T,V") = ^(A.9,e,V)
let (d n cmd, V*) = W(X, 7, a V)
kt (Ca.ft cmd, V") m W(A,7, ca, V*)
,
,
in
while
(CUd Ud U{r = ft =ft,a< f^o cmd, V'w U{or})
or
j?V"
edoc:
fet(C,r V') = ^(A,7,e,K)
let (C, f* cmd, V") - W(X, 7,
l
in
ei vmi e 3
(C U
c,
K*)
C U \t = f, a <r), a cmd, V"U{a})
a g.V"
:
= W(A
let(C,r',V')
1
7,e3 ,K)
esse c\ of
x
:
if
t(x)
=
(C U {A(0
I:
default
let var
i := t in c
:
= f occ then
= ?,«<?*}, a cmd, V'u{or})
r oar or t(x)
(C U {r
= ?*, o<r*}, or cmd, V^U {or})
V
a^V
o
tf
fail
:
n=
kt (C,r cmd,V") m
^(A.7,e,V0
W{\,t[z :? oarlcV)
cmd,V")
let(C,f>
in
(CuC.f
Ictproc x(in xi, Inout x 3 out xs) c in c'
kt (C,w, V") = W(A,7,proe (in xi, Inout x a ont x») c,V)
n
let (C,rcmd,V ) = W{\,y,\proc (in x,, inout x 3 out x s ) c/xk', V)
:
,
,
,
infCuC.rcmd.K")
e(ei>«a,es}:
kt (C,t prcefn,
ft oar, ft
kt(C,r',V) =
rr'(A,7.ei.K')
kt
C = ewe
x:
a«),
V) = W(\,y,e,V)
e 3 of
7X*)*^'twtkenCuC"u{? = n,r"=:ra}
CuCu{f = T ,X(l) = ri )
if
eke
fail
,
I:
l
default
r
fail
in case « 3 of
x
I
:
:
if
y(x)
»**«« « 7(x) = r"
eke fail
(C" U (A(J)
ace then
(Cu {?" - ft}, f cmd, V")
n ft},? cmd, V)
default :fail
Figure
2.
Volpano-Smith Type Inference Algorithm
12
type variables V.
maps
A
location typing
maps addresses
some
x.
The
treats free addresses.
We
variables to types x and x var, for
program, while the former
X from
addresses, and drop
contains a
list
to x types
and an
latter treats free variables in a
shall
assume programs have no
the implementation of the type inference algorithm.
of previously-used type variables and allows the algorithm
type variables. If the algorithm succeeds,
returns a triple consisting
it
constraints C, a type n, and the updated set of stale variables V.
inequalities
To
Figure
3,
identifier typing
among
The
to
of a
The
set
V
new
choose
set
free
of
constraints in
C
are
type variables.
illustrate
how the
of a procedure
we
algorithm works,
give an example from
that indirectly copies a variable
proc (in
shown
x to another variable
in
y.
out y)
x,
x
letvar a :=
letvar
[3],
b
:= :
while
z
in
0in
i>0do
b:= b+1;
a := a-1;
y:=b
Figure
3.
Example Program
Figure 4 shows the results of calling the algorithm on the procedure. The algorithm yields
a triple consisting
of a
set
of stale type variables V, the
the type of the procedure, here denoted
by n
This
.
list
of generated constraints and
triple is
used to form the principal
type for the procedure.
Type simplification can be used
The
static
to simplify the constraint set
C
and type n
[8].
analyzer developed for this thesis does not include any mechanism to perform
type simplification and such simplification
is
shown
13
here for demonstration purposes
v=
{
c=
{cc<y v =
rj
=
7T
Figure
only.
(v
=
0,
8<
proc(or,
£
i,
v, 8,
s=i,
o,
rj,y
=
k,
rj,
9, k,
X, p, £}
v<£,£=£y<£,
u<y, k= A, y<K
i
=
fi
=
v,
<£
8=
rj,
i
<8,
o<p, S<
£}
Pace))
Algorithm Results of Sample Program
4.
The
form, as
y, v, o, e,
a.
step collapses the strongly connected types
first
shown
in
Figure
V=
c=
K=
5.
{a, o,
8,
(o proc(a,
is
5.
6.
2,
ace))
Algorithm Results after Type Simplification
possible leading to the
7t
Figure
£}
{8<$,o<X,X<8, a<X\
Figure
Further simplification
and produces a more useful
Principal
Type
%
in
Figure
6.
= (£proc(£ £ ace))
after
Applying Monotonicity-Based Instantiations
14
V.
IMPLEMENTATION OF THE TYPE INFERENCE ALGORITHM
The
static
analyzer that performs the security checks specified by the type
was developed using
inference algorithm
takes, as input, a
grammar
specification.
JavaCC
the Java Compiler Compiler (JavaCC).
The output
is
a Java program that will parse the
specified language and perform the semantic actions indicated in the
grammar
specification.
Rather than
in
Figure
1,
we
start
from scratch and build a JavaCC specification for the language
started with a
reflect the language in Figure
inference algorithm.
restrictions
The
grammar
1
.
specification for Java 1.0.2,
to
Semantic actions were added to encode the type
specification
is
given
in
Appendix A. There are
imposed on the kinds of Java programs
because there are many constructs
the type inference algorithm.
which we modified
in the
that the static analyzer
several
can check
Java language that are not currently treated
Each of the phrases
in
Figure
1
was mapped
in
to a
corresponding expression or statement in the Java grammar specification.
A.
A BRIEF LOOK AT JAVACC
JavaCC constructs a Java program
that acts as a recursive descent parser for the
language described by the grammar specification.
specification
is
shown
in
Figure
7.
The sample shows
parse a Java method declaration and parameters.
method
in the
A sample
generated parser.
15
from the Java
1.0.2
grammar
three productions that are used to
JavaCC converts each production
into a
voxd MethodDeclarator
(
:
)
U
{
<IDENTIFIER> FormalParameters
(
)
"["
(
"]"
)*
}
void FormalParameters
(
)
:
{}
l
"("
FormalParameter
[
()
"," FormalParameter
(
(
)
)*
]
")"
}
void FormalParameter
(
)
:
{}
{
Type() VariableDeclaratorId(
}
Figure
7.
Each production begins with
which
parser,
void
is
will also be the
name of the method
is
FormalParameter
(
)
and
way
it is
in the parser.
}".
added code
in the
The name of the production
Parameter passing can be adding to the
(
)
generated parser. For example,
in Figure 7 is called,
VariableDeclaratorld
When JavaCC
will
in the
used in Java programs.
Java code can be added anywhere
braces, "{
of the corresponding method
a notion of "calling" a production because of its relationship with the
corresponding method
Type
the return type
for the three productions in Figure 7.
productions in the same
There
Sample Productions
it
was
production should be inserted in the
shown
)
production
will in turn call the productions
.
in the production, but
converts the production into
remain where
three productions
(
it
if the
its
must be enclosed
in curly
corresponding method, the
placed. Local variable declarations for any
first set
of curly braces of that production. In the
in Figure 7, there are
16
no
local variable declarations.
IMPLEMENTING THE ALGORITHM USING JAVACC
B.
There are two main data structures
first is
called
gamma, and
in the
implementation of the algorithm. The
contains identifier typings.
The second
is
called
triple, and
consists of the items returned by the type inference algorithm, namely, a set of constraints
C, a type n, and a
The
list
initial
attempt to implement the algorithm used two Stacks from the Java
package. The
utility
of stale type variables V.
gamma
consisted of a variable
stack held objects called
name and
its
gamma
type variable. The triple stack contained the triple
items consisting of the constraint set in the form of a linked
The
set
A gamma item
items.
of stale type variables was kept
in
list
and the principal type.
a separate symbol generator for the entire
program.
The
idea
of the
was encountered and
gamma
to
pop
apparent that determining
stack
was
the stack
when
to
when
push a
gamma
item whenever a
the variable's scope ended.
the variable's scope ended
was going
It
new
variable
became
to be a difficult task
unless the analyzer kept track of more information about the variables being declared.
The analyzer soon had four separate
The
triple stack
It
stack
that
was
is
stacks to keep track of the important information.
had similar problems.
was determined
utilized.
that
all
of the external stacks could be eliminated
In this implementation,
gamma became
a linked
list
passed as a parameter from one production to those productions
if the
run time
of gamma items
it
calls. In
addition, each production returns a triple that contains all the constraints generated in the
program. This did pose one problem.
A local variable declaration requires an update to
17
the
gamma
new
list
with the variable's type information and
triple item.
Both must be returned
This problem
may
it
also requires the generation
to the calling production.
be overcome by adding
new
productions to the specification
but the productions were not added in this implementation. Instead, a
was developed
to simply hold the
gamma
and the generated
the
later
list
new gamma
production that required a
gamma
when
list
list
and the generated
new
data structure
triple so that
both
could be returned. The structure, called Dual, was
triple
updated to also hold a string
of a
a similar situation arose in the method declaration
and the string representation of a token to be
returned.
Each of the commands and expressions of the core language
"mapped"
to
one or more productions
the algorithm to the Java specification
determine which productions
in the
in the
listed in
Figure
1
are
Java 1.0.2 grammar specification. Mapping
was performed
grammar
in
two
steps.
The
first
specification correspond to
step
was
commands
to
or
expressions in the core language. Once the relationship between the core language and
grammar
specification
was
established, the second step entailed
encoding the semantic
actions specified by the algorithm and placing the code in the corresponding productions
of the grammar
Figure
specification.
We consider,
in turn,
each of the cases of the algorithm
2.
Case "x"
The Name
(
)
production in the grammar
file is
returns a string representation of the current token
an instance of case
when
the production
is
x.
Name
called.
(
The
type inference algorithm requires the type of x, x or r var, to be determined. The type
18
in
resolution of the token that corresponds to x
Name
(
is
performed within the production
that calls
)
Case "n"
The Literal
(
)
production
is
an instance of case
Literal
n.
Java primitive types of integers, floating point numbers, characters,
()
strings,
accepts the
boolean
values "true" and "false", and "null".
Case "1"
The
third case statement,
/.
deals with locations and
is
not implemented in the
e2
;
Java grammar.
Case "ei +
e2
"
The expressions below
of case
are all instances
ConditionalOrExpression
ConditionalAndExpression
InclusiveOrExpression
ExclusiveOrExpression
AndExpression
EqualityExpression
RelationExpression
Shif tExpression
AdditiveExpression
MultiplicativeExpression
ei
+
(
(
(
(
(
(
(
(
(
(
Case "proc(in
xi,
The case
algorithm for procedure declarations has the following form:
in the
inout x 2 , out x 3 ) c"
proc( in Xi, inout x 2 out X3) c
,
The modes of the parameters,
in; inout;
and out, are similar to those used
programming language. The productions dealing with procedures
MethodDeclaration
(
)
production.
starts
in the
Ada
with the
The name of the procedure and the parameters
19
are treated in a call to the
added
may
to the
MethodDeclarator
environment with a
call to the
(
)
production.
The parameters
Forma lParameters
be referenced in the body of the procedure.
(
)
are
production so they
MethodDeclarator
returns the
)
(
procedure name and the types of the parameters. All parameters are considered to be
inout
mode and
are typed as such,
body of the procedure,
c, is
meaning they have type
handled
Block
in a call to the
x var for
(
)
some
production.
Finally the
x.
The
static
analyzer does not handle recursive procedures or method declarations.
Case
"ci; C2"
Next
in the
a block, delimited
The
original Java
production.
It
algorithm
by
{
} ,
the statement for composition, Ci; C2. Composition within
handled by the
is
grammar
is
BlockStatementList
specification handled composition in the
was necessary
add the production
to
(
)
production.
Block
(
BlockStatementList
(
)
to
handle the letvar statement. Changes to the grammar specification for the letvar
statement are explained later in this section.
Case
"if e then ci else C2"
If-then-else statements are handled by the
grammar
is
The
specification.
else portion
If Statement
of the statement
is
(
)
production
in the
not mandatory in Java. If it
not used, then the semantic actions in the algorithm pertaining to the else statement are
not executed.
Case "while
e
The next case
both the
do c"
is
the while loop of the form, while e
WhileStatement
(
)
and
DoStatement
specification.
20
(
)
do
c.
It
has been
productions
in the
mapped
Java
to
Case "x := e"
The assignment statement x
:= e
mapped
is
Assignment
to
(
)
Note
.
that
"
="
:
is
not the only assignment operator allowed; others include: "*=", "/=", "+=", and "-=".
A
modification to the
specification
grammar
Assignment
PrimaryExpression
Expression
(), or
also called from a
(
(
,
)
specification
production
)
may
be evaluated as a
number of other productions
(
PrimaryExpression
Grammar
production,
specification.
referenced in
(
y,
It
Figure
1.0.2
grammar
The production,
8.
literal
()
The Java
here.
(
)
,
Name
(
)
PrimaryExpression
.
)
(
production requires that
)
of x from the
identifier typing y.
PrimaryLef tExpression
(
returns the string representation
of x, so
PrimaryExpression
(
)
)
,
was introduced
in the
that
it
may
For
be
Assignment
(
:
{}
{
PrimaryExpression
(
)
AssignmentOperator
}
Figure
8.
Assignment Production
2]
(
)
this
into the
production.
()
is
as well and those productions require that
Assignment
return the type
)
and replaces
void Assignment
(
return a triple consisting of a constraint set, a type, and a
)
of stale type variables. However, the
new
is listed in
AllocationExpression
PrimaryExpression
reason, a
was required
Expression
list
Case "letvar x := e
Mapping
to the Java
in c"
the letvar statement to the Java language required another modification
grammar
specification.
same
declarations at the
The
original specification handled local variable
BlockStatement
level as all other statements within
(
original Java specification productions that handle local variable declarations are
in
Figure
)
The
.
shown
9.
void Block
(
:
)
{}
{
"{"
BlockStatement
(
()
"}"
)*
void BlockStatement
LOOKAHEAD(Type() <IDENTIFIER>)
"
LocalVariableDeclaration
;
(
Statement
)
(
void LocalVariableDeclaration
Type
(
)
VariableDeclarator
(
)
(
"," VariableDeclarator
}
Figure
9.
Java Specification Productions to Handle Local Variable Declarations
In the original
production.
parentheses
The
is
*
grammar
specification, composition
is
handled
in the
Block
(
operator indicates that the production(s) within the preceding set of
called zero or
BlockStatementList
specification because
it
is
(
more
)
and
times.
Two new productions,
LetvarStatement
(
)
,
were added
necessary to pass the identifier typing
for x, to the production that parses c in letvar x
specification had no productions specified for
22
c,
=
e in
so
c.
The
y,
grammar
to the
updated with a typing
original Java
1
grammar
.0.2
BlockStatementList
(
)
was
introduced to handle this problem. In the modified
calls
BlockStatementList
BlockStatementList
BlockStatement
LetvarStatement
Statement
is
()
)
,
once per
)
(
if
)
called.
new
variable.
The
(
)
The next case
(
)
all
algorithm
static
(
.
)
is
to parse the rest
found, otherwise.
first calls
of the program that
grammar
x(in Xi, inout X2, out X3)c in
file is listed in
is
within the scope the
Figure 10.
"
c'
in the type inference algorithm, letproc,
methods
calls
)
(
allows procedures to be
Java grammar specification.
in the
in the
are allowed because that
is
analyzer specification.
the only kind
of method the
treats.
Case
The
"e(ei, e 2 , e3 )"
final
case in the algorithm types procedure
handles procedure calls in the
name of the procedure
are
(
procedures are treated as monomorphic
Moreover, only
Block
to handle the declaration, then
used polymorphically and was not implemented
Therefore,
)
(
BlockStatement
LetvarStatement
section of the modified
Case "letproc
BlockStatement
a local variable declaration
LocalVariableDeclaration
BlockStatementList
specification,
the production used to handle composition, calls
zero or more times.
)
(
(
(
grammar
is
compared with those
PrimaryPref ix
found
in the identifier
retrieved
from
y.
The
(
)
calls.
The Java
production. First, the
typing
,
original
y,
then the types of the arguments
grammar
specification for Java
allowed arguments to be expressions. In the modified specification,
be either a
literal
specification
all
or a previously declared and initialized variable name.
23
parameters must
void Block
Bio ckStatement List
void BlockStatementList
BlockStatement
L00KAHEAD(2)
(
)
)+
void BlockStatement
LOOKAHEAD( Type
LetvarStatement
Statement
(
<IDENTIFIER>
)
(
(
void LetvarStatement
(
)
:
LocalVariableDeclaration
(
)
"
;
(
)
void LocalVariableDeclaration
BlockStatementList
"
:
{}
{
Type() VariableDeclarator
(
(
)
"," VariableDeclarator
1
Figure 10. Specification Changes for letvar Statement
All of the source code files used to
implement the
static
analyzer are given in
Appendix B.
C.
RESTRICTIONS IMPOSED ON PROGRAMS
The type inference algorithm
in [3]
does not
treat
an object-oriented language like
Java. Although
we
analyzer for
Java but rather an analyzer for that subset of Java corresponding to the
full
started with a
simple language in Figure
1
.
So
JavaCC
how
big
specification for Java, the result
is
this subset?
24
was not an
subset that can be analyzed has no objects, and consequently no instance
First, the
variables or instance methods.
Second,
all
expressions must be free of any side effects. This
assignment expressions
"expressions".
They
all
in
is
the reason that
Java are prohibited, as are pre and post increment
violate the confinement property.
Other restrictions on Java programs include that they be closed (no free
variables), that they
have only non-recursive
static
methods, that they have no methods
with a return type other than void, and that they have no forward references. Yet, other
restrictions are
[3].
imposed because certain constructs were not treated
They include
try-catch blocks, synchronized blocks and so on. In
following features of Java are not analyzed:
Static Initializes
1
2.
Arrays
3.
Explicit Constructor Invocation
4.
Conditional Expressions
5.
Instanceof Expressions
6.
Preincrement and PreDecrement Expressions
7.
Postincrement and PostDecrement Expressions
8.
Cast Expressions
9.
Allocation Expressions
10.
Labeled Statements
1 1
12.
13.
14.
15.
-
Break Statements
Continue Statements
Return Statements
6.
Throw
1
7.
Synchronized Statements
Try Statements
Catch Statements
19.
(object creation)
Switch Statements
For Statements
1
18.
in the
Statements
20. Finally Statements
25
algorithm of
summary, the
The constructs
grammar
specification
implementation
that
have been disallowed have only been commented out
file listed in
in the future.
Appendix
A
in
order to allow for their
This means they cannot be parsed in the current
implementation.
26
in the
VI.
AN EXAMPLE RUN OF THE STATIC ANALYZER
The program
in
Figure
1 1
illustrates
an application of the
corresponds to the example program of Figure
However,
mode
it
is
III,
not identical, for Java has no parameter-passing
out. Nevertheless,
analyzer
Chapter
3, in
when run on
this
program are shown
in
It
written in Java.
mode corresponding
The
serves to illustrate the analyzer.
it
static analyzer.
results
of the
to
static
Figure 12.
class test
{
public static void p(int
x,
int y)
{
int a = x;
int b = 0;
while (a > 0)
b = b + 1;
a = a
-
{
1
}
y = b;
}
}
Figure
1 1
.
Static
Analyzer Test Program
v=
{to, Ti, 12, T3, t4, X5, X6, X7, X8, T9, X10,
Tn,
c=
{Th =
<
13
7t
=
<
T12,
T 6 Ill
.
=U,
X5
T2,Tl0
=
Xl2<t4, X 8
<
X9,T 9
=
=
X4 X 2
,
X9, ^2
<
T12, T13, T14}
I4,
Tn =
T 9 , Tl4
<
Tg,
18
Tl3, Tl
<
^6, T 6
= TB
,
T3
=
T3,
< Xl3,
X7
X
=
<
T6,
T2}
X12 proc(Tovar, Xivar)
Figure 12. Test Program Results
We
y
,
are the
sketch a trace of the analyzer on part of the program. The parameters, x and
first
tokens to be analyzed. They are assigned the type variables xo and
27
Xi
Then
respectively.
the variable declaration:
int a = x
is
analyzed.
{to
<
T2}
is
A new type
The
generated.
upward coercion
is
namely
variable for x,
constraint
is
created and the constraint set
T2, is
generated by the case for identifiers where an
introduced (see Figure
2).
The
variable a
is
assigned the type
variable T2 in analyzing the rest of the program.
Next, the variable declaration:
int b is
analyzed
in the
This
integer.
is
same manner, except
the integer
assigned the type variable
At
this point,
{x
and only one constraint,
to
< T2,
no constraint
is
generated since
is
an
case of the type inference algorithm. Finally, b
literal
T3.
that
:
i
,y
:
gamma
Ti,a
:
is
contains the following types:
i2 , b
:
t3
}
exists.
Next, the while loop
while
is
analyzed. The predicate, a
>
0, is
(a
checked
>
0)
first
and generates the following
new
constraints:
T2
The
first
comes from the
identifier case
and the second comes from
where
X,
= x 4 and
x2
=
xs
x,
The
<
T4, 14
=
T5
of the algorithm (upward coercion of a's type)
= x2
in the
rest
of the program
case for
28
ei
is
+
ei in the
algorithm of Figure 2,
analyzed in the same manner.
VII.
As we
rely
CONCLUSIONS
more on computer systems, secure flow analysis
protect the information stored
on these systems. Denning's work
base of knowledge for secure information flow. The Lattice
bound
a
statically or
lattice,
dynamically to a security
hence the name.
security classes.
The
A flow relation
lattice
Volpano and Smith
shows
all
provides a good
consists of a set
Each storage object
is
is
Security classes are required to form
indicates permitted information flows
between
They
model
in the
context of a type system and prove
also give a type inference algorithm for the
The
system. This thesis describes an implementation of that algorithm using JavaCC.
result
of
allowed information flows within the system.
[3] treat the
the soundness of the type system.
class.
a necessary tool to
[1] [5]
Model
storage objects, a set of processes, and a set of security classes.
is
a static analyzer that checks for secure information flow at compile-time.
The
static
analyzer can only analyze a subset of the Java
1
.0.2 language.
It
may
be too limited to allow one to write interesting and useful programs. Future work might
focus on analyzing a larger subset of Java.
29
30
LIST
1
Denning, D. E. and Denning,
P. E., "Certification
Flow." Communications of the
2.
OF REFERENCES
ACM,
vol.
20
of Programs for Secure Information
no. 7, pp. 504-513, July 1977.
Goguen. J. and Meseguer, J., "Security Policies and Security Models,
192 IEEE Symposium on Security and Privacy, pp. 1-20, 1982.
"
Proceedings
1
3.
"A Type-Based Approach to Program Security,"
Colloquium on Formal Approaches in Software
ofTAPSOFT
Volpano D, and Smith,
Proceedings
G.,
'97,
Engineering, 14-18 April, 1997.
4.
"Java Compiler Compiler," Sun Microsystems.
http://www.suntest.com/JavaCC/index.html
5.
Denning, D.
the
6.
ACM,
E.,
"A
Lattice
vol. 19 no. 5, pp.
Volpano, D., Irvine,
C,
Model of Secure Information Flow," Communications of
236-243,
May
1976.
"Secure Flow Typing," Computers and Security, vol. 16 no. 2,
pp. 137-144,1997.
7.
Volpano, D., Irvine, C, and Smith, G., "A Sound Type System for Secure Flow
Analysis," Journal of Computer Security, vol. 4, pp. 167-187, 1996.
8.
Smith, G., "Polymorphic Type Inference for Languages with Subtyping and
Overloading," Cornell University, Technical Report, 91-1230, 1991.
31
32
APPENDIX A - JAVA
The following pages
is
GRAMMAR SPECIFICATION
represent the modified Java 1.0.2
the input to the Java Compiler Compiler
Sriram Sankar on 6/1 1/96 and
were added
1.0.2
to the original
is
The
original
grammar
grammar
file
was developed by
copyrighted by Sun Microsystems Inc
grammar
to
specification that
Semantic actions
perform secure flow analysis on a subset of Java
programs
33
*
Copyright
(C)
1996,
1997 Sun Microsystems Inc.*
*
*
*
*
Use of this file and the system it is part of is constrained by the
file COPYRIGHT in the root directory of this system. You may,
however, make any modifications you wish to this file.
*
*
*
*
Java files generated by running JavaCC on this file (or modified
versions of this file) may be used in exactly the same manner as
Java files generated from any grammar developed by you.
*
*
*
*
*
Author: Sriram Sankar
Date: 6/11/96
This file contains a Java grammar and actions that implement a
front-end.
*
*
Modified 24 Feb 98 by LT James
D.
Harvey,
USN.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
Modifications have been made to incorporate a type checker into the
compiler. Several portions of the Java language have been disabled
in this version because the type checker does not support them. The
portions that are not implemented are as follows:
Static Initializers
Arrays
Explicit Constructor Invocation
Conditional Expressions
Instanceof Expressions
Preincrement and PreDecrement expressions
Cast Expressions
Allocation Expressions
Labeled Statements
Switch Statements
For Statements
Break Statements
Continue Statements
Return Statements
Throw Statement
Synchronized Statement
Try Statement
*
*
*/
#
Permission to reproduce has been obtained from Sriram Sankar of Sun Microsystems.
34
options
LOOKAHEAD = 1;
JAVA UNICODE ESCAPE = true;
{
PARSER_BEGIN JavaParser
(
import thesis.*;
public class JavaParser
{
static SymbolGeneratcr sg = new SymbolGenerator
public static void main (String args[])
JavaParser parser;
Triple ConstraintSet;
Gamma gamma = new Gamma "my Gamma"
(
)
{
(
if
)
(args. length == 0)
Reading from
System. out .println "Java Parser Version 1.0.2:
.");
standard input
parser = new JavaParser (System. in)
else if (args. length == 1)
Reading from file
System. out println "Java Parser Version 1.0.2:
" + args[0]
.")
+ "
try
parser = new JavaParser (new Java io FileInputStream(args 0]
;
catch Java io FileNotFoundException e)
System. out .println "Java Parser Version 1.0.2:
File " +
"
args[0] +
not found.");
return;
{
(
.
}
.
{
(
.
.
.
{
.
.
}
.
[
.
{
(
(
}
}
else
System. out .println "Java Parser Version 1.0.2:
Usage is one
of:")
System. out .println
Java JavaParser < inputf ile"
System. out .println ("OR")
System. out .println
Java JavaParser inputfile");
return;
{
(
(
)
(
}
try
{
ConstraintSet = parser CompilationUnit (gamma)
System. out .println "Java Parser Version 1.0.2:
Java program
parsed successfully.");
catch (ParseError e)
System. out println "Java Parser Version 1.0.2:
Encountered
errors during parse.")
.
(
]
{
(
.
,-
1
i
;
}
PARSER END (JavaParser
35
)
)
SKIP
I
I
I
I
/*
:
WHITE SPACE */
"\t"
"\n"
"\r"
"\f"
SPECIAL_TOKEN
:
/*
COMMENTS
V
{
<SINGLE_LINE_COMMENT: "//" ~ "\n", "\r " *
("*"
<FORMAL_COMMENT: "/**" (~[" + "]) i "'*
(
[
]
(
'"
I
I
<MULTI_LINE_COMMENT: "/*"
TOKEN
(-["*"])* "*"
"/">
"*") )*
:
/*
RESERVED WORDS AND LITERALS */
{
<
<
<
<
<
<
<
<
ABSTRACT: "abstract" >
BOOLEAN: "boolean" >
BREAK: "break" >
BYTE: "byte" >
CASE: "case" >
CATCH: "catch" >
CHAR: "char" >
CLASS: "class" >
CONST: "const" >
CONTINUE: "continue" >
_DEFAULT: "default" >
<
<
<
< DO: "do"
< DOUBLE:
>
"double"
>
< EXTENDS: "extends" >
< FALSE: "false" >
< FINAL: "final" >
< FINALLY: "finally" >
< FLOAT: "float" >
< FOR: "for" >
<
<
<
<
<
<
<
<
<
<
<
GOTO: "goto" >
IF: "if" >
IMPLEMENTS: "implements" >
IMPORT: "import" >
INSTANCEOF: "instanceof" >
INT: "int" >
INTERFACE: "interface" >
LONG: "long" >
NATIVE: "native" >
NEW: "new" >
NULL: "null" >
< PACKAGE: "package ">
< PRIVATE: "private" >
< PROTECTED: "protected" >
< PUBLIC: "public" >
< RETURN: "return" >
36
"\n" "\r" "\r\n")
" +
(-["*","/"]
|
)
I
|
(
("*"
!
(~
["*","/"]
[
"
*
]
)
(-["*"])*
SHORT: "shore" >
STATIC: "static" >
< SUPER: "super" >
< SWITCH: "switch" >
<
<
"synchronized"
<
SYNCHRONIZED:
<
<
THIS: "this" >
THROW: "throw" >
THROWS: "throws"
<
<
<
<
<
<
<
>
TRANSIENT: "transient"
TRUE: "true" >
TRY: "try" >
VOID: "void" >
VOLATILE: "volatile" >
WHILE: "while" >
TOKEN
>
LITERALS */
/+
:
>
{
<
INTEGER_LITERAL:
["1", "L"]
<DECIMAL_LITERAL>
<HEX_LITERAL> (["1","L"])?
(
)
I
sUtirtii ijiitiKAjj/
I
1
-L
[
,
j
J_i
i
:
>
i
i"-"9"
<
#DECIMAL LITERAL:
<
#HEX_LITERAL:
<
#OCTAL LITERAL:
<
FLOATING_POINT_LITERAL:
["
(["0"-"9"])*
]
>
I
"0"
["x","X"]
[
(
"0"- "9" "a"-"f " "A"-"F"
,
,
]
I
"0"
(
[
"0"-"7"]
)
>
*
I
[
(
(
"
"-"9
"
]
)
+
["0"-"9"]
"."
)
(
["f", "F", "d", "D"]
"." (["0"-"9"])+
(<EXPONENT>)
*
)
I
(<EXPONENT>)
,
[
"f ", "F" "d", "D"
["0"-"9"] )+ <EXPONENT>
"f " "F" , "d" "D"
["0"-"9"] )+ (<EXPONENT>) ?
"f " "F" "d", "D"
?
(
,
I
(
|
(
(
[
,
]
)
,
[
>
I
<
^EXPONENT:
<
CHARACTER_LITERAL:
(["+","-"])?
["e","E"]
(["0"-"9"])+ >
I
ii
i
it
,"\\","\n","\r"]
(-[
(
I
)
("\\"
/
rn n n
r
|
I
r
"Q"
"3"
"y-lt
**K"
t|j_it
"0"-"7"]
I
ii\\it
ii^rit
[
"
]
)
)
II
I
nil!
"-"7"
r"Q"-"7"i r"Q»_»"7"'|
(
II
37
I! \
I! 11
-l
]
)
)
+
>
<
5TRING_LITERAL:
(~["\"" "\\", "\n", "\r"]
("\\"
t
(
i
(
|
I
["n","t","b","r","f","\\",""
t"0"-"7"]
[
"
o
"— "3
"
]
(
l"0'
!
-
::
7"]
["0"-"7"]
)?
["0"-"7";
)
*
)
TOKEN
<
:
/*
IDENTIFIERS */
IDENTIFIER: <LETTER>
#LETTER:
"\u0024",
"\u0041"= "\u005a",
"\u005f",
"\u0061"- "\u007a",
n
\u00c0"- "\u00d6",
"\u00d8"- "\u00f6",
"\u00f8"- "\u00ff",
"\u0100"- "\ulfff",
"\u3040"- "\u318f",
"\u3300"- "\u337f",
"\u3400"- "\u3d2d",
"\u4e00"- "\u9fff",
"\uf900"- "\ufaff"
<
#DIGIT:
"\u0030""\u0660""\u06f0""\u0966""\u09e6""\u0a66""\u0ae6""\u0b66""\u0be7"
"\u0c66""\u0ce6""\u0d66""\u0e50""\uOedO""\ul040"=
"\u0039"
"\u0669"
"\u06f9"
"\u096f"
"\u09ef"
"\u0a6f"
"\uOaef"
"\u0b6f"
"\uObef"
"\u0c6f"
"\uOcef"
"\u0d6f"
"\u0e59"
"\u0ed9"
"\ul049"
(<LETTER> <DIGIT>]
|
r
\""]
<
"X.
L PAR EN
"
nn7\ n pi\t
tt
>
1
(
\
i
^
'
>
'
>
)
1
<
<
1
<
1
<
V
1
1
<
<
LBRACE
RBRACE "}
LBPACKET
RERACKET
SEMICOLON:
COMMA: ","
" >
"
DOT
ii
r
t
*["
>
']"
>
r
>
:
TOKEN
OPERATORS */
/*
"=" >
">" >
"<" >
BANG: "!" >
TILDE: "~" >
HOOK: "?" >
COLON: ":" >
E q: «==» >
LE: "<=" >
GE: ">=" >
NE: "!=" >
SC_OR: "||" >
ASSIGN:
GT:
LT:
SC AND: "&&"
INCR:
DECR:
PLUS: " + " >
MINUS:
+
STAR:
SLASH: "/" >
BIT_AND: "&" >
BIT_OR: " " >
XOR: " A " >
REM: "%" >
LSHIFT: "«" >
:
11
V,
11
|
RSIGNEDSHIFT:
RUNSIGNEDSHIFT
PLUSASSIGN: "+=" >
_
MINUSASSIGN
«
+
STARASSIGN:
>
SLASHASSIGN: "/=" >
ANDASSIGN: '*& = " >
ORASSIGN: "|=" >
XORASSIGN: " A = " >
REMASSIGN: "%=" >
LSHIFTASSIGN: "<<=" >
RSIGNEDSHIFTASSIGN: ">> = "
< RUNSIGNEDSHIFTASSIGN: ">»=
'
fl
If
-^
39
*
THE JAVA LANGUAGE GRAMMAR STARTS HERE
*
*•**• + + + + + '*•'*•******- +
++
•*•** + + + + + + + + * + + + +
++ *+*+
/*
*
Program structuring syntax follows.
*/
Triple CompilationUnit (Gamma gamma)
{Triple cs = null;
:
i
PackageDeclaration!)
)*
ImportDeclaration
cs = TypeDeclaration (gamma
<EOF>
return cs;
//[
//
]
(
(
)
(
*
)
)
{
void PackageDeclaration
{
(
:
)
}
{
"package" Name
(
";
)
void ImportDeclaration
(
:
)
{}
{
"import" Named
[
"•"
"+ "
]
";"
}
Triple TypeDeclaration (Gamma gamma)
{Triple cs = null;}
:
{
(LOOKAHEAD(
(
"abstract"
I
"final"
I
cs = ClassDeclaration (gamma
I
Interf aceDeclaration (gamma)
I
"
{
;
"
return cs
;
/*
*
V
Declaration syntax follows.
40
"public" )* "class"
Triple ClassDeclaration (Gamma gamma)
:
i
i
Triple cs = null;
Dual d = new Dual cs gamma
(
,-
)
;
}
{
"abstract"
"final"
"public" )*
"extends" Name
"class" <IDENTIFIER>
"{"
d = ClassBodyDeclaration (d. gamma)
(
|
|
[
(
)
[
]
)
(
*
"implements" NameList
"}"
r
i
if
(d
null)
!=
return d
.
cs
I
else
return cs;
}//end if
{
Dual ClassBodyDeclaration (Gamma gamma
{
Triple cs = null;
Dual d = null;
L00KAHEAD(2)
Staticlnitializer
(
I
*/
LOOKAHEAD(
"public"
"protected"
cs = ConstructorDeclaration (gamma)
{d = new Dual (cs, gamma)
[
|
"private"
|
Name
]
(
)
"("
)
;
I
LOOKAHEAD
MethodDeclarationLookahead
{
(
)
)
d = MethodDeclaration (gamma
I
d = FieldDeclaration (gamma)
)
{
System. out println "Constraint set: " + d.cs);
" + d. gamma);
System. out println "Gamma
return d;
(
.
(
:
.
}
1
// This production is to determine lookahead only,
void MethodDeclarationLookahead
(
{
)
:
)
{
"private"
"public"
"protected"
"native"
"final"
"synchronized" )*
ResultType
< IDENTIFIED "("
(
|
|
|
I
(
)
}
41
|
"static"
|
"abstract"
I
(
void Interf aceDeclaration (Gamma gamma)
Triple cS = null;
:
"abstract"
"public" )*
"interface" <IDENTIFIER>
"extends" NameListO
+
"{"
"}"
Interf aceMemberDeclaration (gamma
(
|
[
)
(
)
void Interf aceMemberDeclaration (Gamma gamma)
:
}
LOOKAHEAD( MethodDeclarationLookahead
MethodDeclaration (gamma)
(
)
)
FieldDe clara t ion (gamma)
Dual FieldDeclaration (Gamma gamma)
:
Dual d = null;
"public"
"protected"
"private"
"transient"
"volatile" )*
Type
d = VariableDeclarator gamma
(
!
I
I
"static"
|
"final"
I
I
(
)
(
)
";"
{
return d;
}
}
Dual VariableDeclarator (Gamma gamma)
:
>
Triple cs = new Triple sg .NextSymbol (),"")
String id;
(
}
{
id = VariableDeclaratorld
cs = Default
(
)
(
)
(
"=" cs = Variablelnitializer (gamma)
)
{
gamma - gamma .Append (new Gammaltem(id, cs getType
Dual d = new Dual(cs, gamma);
return d;
.
i
i
)
Triple Default
(
)
:
{}
{
{return new Triple sg .NextSymbol
(
()
,
}
42
"");)
,
(
)
"var"
)
)
;
String VariableDeclaratorld
String id;
(
:
)
{
{
<
IDENTIFIED
{id = token image
.
;
(»[»»]»)*
//
return id;
{
)
Triple Variablelnitializer (Gamma gamma)
{Triple cs = null;}
:
{
/*
"{"
)*
]
[
Variablelnitializer
()
(
L00KAHEAD(2)
"," Variablelnitializer
")"
","
[
]
I
*/
cs = Expression (gamma
return cs;
(
}
Dual MethodDeclaration (Gamma gamma)
:
t
Triple cs = null;
Dual d = new Dual cs, gamma
Gamma temp;
Gamma param = new Gamma "param"
(
)
(
)
)
{
"public"
"protected"
"private"
"native"
"final"
"synchronized" )*
ResultType
temp = MethodDeclarator (gamma, d)
(
|
I
|
I
"static"
"abstract"
I
|
(
{
whi 1 e
(
!
(
t emp
.
i s Emp t y
(
)
)
)
{
Gammaltem gi = (Gammaltem) temp getFromList
gamma = gamma .Append (gi
param = param. Append (gi
temp = temp. removeFromList
//end while
.
()
;
)
)
(
}
)
;
}
[
"throws" NameListO
(
cs = Block (gamma)
]
";"
I
)
{
Gammaltem GI = new Gammal tern (d. id, cs getType
GI setParam (param)
d. gamma = d. gamma .Append (GI
return new Dual (cs, d. gamma)
.
.
)
}
43
(
)
,
"proc");
I
Gamma MethodDeclarator (Gamma gamma,
String id;
Dual
d)
:
{
{
<IDENTIFIER> {id = token image
"[" "]"
gamma = FormalParameters
.
(
;
)
+
(
)
{
d.id = id;
return gamma;
!
)
Gamma FormalParameters
{Gamma temp = new Gamma "temp"
(
)
:
(
);
{
"("
*
)
]
{
temp = FormalParameter (temp)
[
"
"," temp = FormalParameter temp!
(
(
"
)
return temp;
Gamma FormalParameter (Gamma gamma)
String id;
:
{
{
Type
(
)
id = VariableDeclaratorld
(
{
gamma = gamma .Append (new Gammaltem id, sg Next Symbol
return gamma;
.
(
,
(
)
"var"
)
}
)
Triple ConstructorDeclaration (Gamma gamma)
{Triple cs = null;)
:
i
"public"
"private"
"protected"
<IDENTIFIER> gamma = FormalParameters
"throws" NameListO
"{" //[ L00KAHEAD(2) ExplicitConstructorlnvocation
cs = BlockStatement (gamma) )* ")"
return cs;
[
|
]
I
(
)
[
(
(
{
/*
void ExplicitConstructorlnvocation
{}
(
"this" Arguments
";"
()
I
"super" Arguments
(
)
"
;
}
44
)
]
]
)
void Staticlnitializer
(
)
:
{}
"static" Block
)
Type, name and expression syntax follows
*
*
(
/
void Type
(
(
)
:
PrimitiveType
(
void PrimitiveType
)
(
Name
I
)
(
)
)
(»[»»]»)*
:
"boolean"
"char"
"byte"
"short"
"int"
"long"
"float"
"double"
void ResultType
(
)
:
"void"
Type()
45
String Name
(
:
)
/*
2 is required below since "Name" can be followed
".*" when used in the context of an "ImportDeclaration"
*
A lookahead of
*
by
a
*/
{
String id;
i
< IDENTIFIED
{id = token image
.
//
LOOKAHEAD
return id;
(
{
(
2
)
;
"
.
"
<IDENTIFIER>
)*
}
void NameList
(
)
:
{}
{
Name
(
", "
(
Named
}*
}
/*
Expression syntax follows.
*
*/
Triple Expression (Gamma gamma)
(Triple cs;
:
{
(
LOOKAHEAD
(
PrimaryExpression gamma
(
)
cs = Assignment (gamma
I
cs = ConditionalOrExpression (gamma)
return cs;
{
}
46
)
AssignmentOperator
Triple Assignment (Gamma gamma)
{
String id;
Triple c s
id = PrimaryLef tExpression
Expression gamma
(
)
AssignmentOperator
(
)
cs
(
Gammaltem item = gamma FindType
.
(id)
if (item != null)
String mod = item. getModif ier ()
mod equals "ace"
if (mod. equals "var"
||
String tau = item. getType ()
(
(
.
)
))
{
String tauPrime = cs getType ()
String alpha = sg. Next Symbol ()
Constraintltem cil = new Constraintltem tau, tauPrime)
Constraintltem ci2 = new Constraintltem tauPrime, tau)
Constraintltem ci3 = new Constraintltem (alpha, tauPrime
cs = cs .Append cil
cs = cs .Append ci2
cs = cs .Append ci3
cs setModif ier "cmd"
cs.setType(alpha)
.
(
(
)
(
(
(
(
.
;
else
System. err println "Secure Parse failed");
System. exit
//end if
{
(
.
(
)
)
}
else
System. out .println "Unrecognized variable
System. exit
)//end if
return cs;
{
(
(
"
+ id);
)
void AssignmentOperator
{}
it_.ii
r - "
'&='
fi
ti
I
na
+
"
_.»i
it
I
tt
I
/="
_
"a
-It
It
I
_L
+="
II
It
»«=»
tt
/*
void ConditionalExpression
ConditionalOrExpression
ConditionalExpression
(
)
(
[
"?" Expression
]
}
V
47
I
">>="
I
">»=
Triple ConditionalOrExpression (Gamma gamma)
:
r
l
Triple csl;
Triple cs2 = null;}
i
csl = ConditionalAndExpression (gamma
ConditionalAndExpression (gamma)
)
(
"| I"
cs2 =
{
if (cs2
!= null)
String taul = csl getType ()
String tau2 = cs2 getType ()
Constraintltem cil = new Constraintltem (taul, tau2
Constraintltem ci2 = new ConstraintItem( tau2, taul
csl = csl .Union (cs2 .Append (cil .Append (ci2
.
.
)
)
)
}
}
)*
{
return csl
;
Triple ConditionalAndExpression (Gamma gamma!
i
\
Triple csl;
Triple cs2 = null;
csl = InclusiveOrExpression (gamma)
InclusiveOrExpression (gamma)
(
"&&" cs2 =
{
if (cs2
!= null)
String taul = csl getType ()
String tau2 = cs2 getType ()
Constraintltem cil = new ConstraintItem(taul tau2
Constraintltem ci2 = new ConstraintItem( tau2 taul
csl = csl .Union (cs2 .Append cil .Append (ci2
.
.
,
,
)
(
)
1
}
)*
{
return csl
;
}
48
)
Triple InclusiveOrExpression (Gamma gamma'
{
Triple csl;
Triple cs2 = null;
csl = ExclusiveOrExpression (gamma
(
)
"|" cs2 =
ExclusiveOrExpression (gamma)
{
if (cs2
!= null)
String taul = csl getType ()
String tau2 = cs2 getType ()
Constraintltem cil = new Constraintltem taul, tau2
Constraintltem ci2 = new Constraintltem tau2 taul
csl = csl .Union (cs2 .Append (cil .Append (ci2
;
.
.
(
)
)
return csl
[
,
(
)
;
Triple ExclusiveOrExpression Gamma gamma!
(
/
\
Triple csl;
Triple cs2 = null;
csl = AndExpression (gamma)
(
""" cs2 = AndExpression (gamma)
{
if (cs2
!= null)
String taul = csl getType ()
String tau2 = cs2 getType ()
Constraintltem cil = new Constraintltem taul tau2
Constraintltem ci2 = new Constraintltem tau2 taul
csl = csl .Union (cs2 .Append (cil .Append (ci2
;
.
.
)
)
return csl;
4
l
)
(
,
)
(
,
)
)
;
Triple AndExpression (Gamma gamma
{
Triple csl;
Triple cs2 = null;
csl = EqualityExpression (gamma)
(
"&" cs2 = EqualityExpression (gamma
{
if (cs2
null)
!=
String taul = csl getType ()
String tau2 = cs2 getType ()
Constraint-Item cil = new ConstraintItem( taul tau2
Constraintltem ci2 = new ConstraintItem( tau2 taul
csl = csl .Union (cs2 .Append (cil .Append (ci2
.
.
)
)
)
,
)
,
)
;
}
}
)*
{
return csl
Triple EqualityExpression (Gamma gamma
{
Triple csl;
Triple cs2 = null;
csl = RelationalExpression (gamma)
RelationalExpression (gamma)
(
(
"=="
|
"!=»
)
CS 2 =
{
if (cs2
null)
!=
String taul = csl getType ()
String tau2 = cs2 getType ()
Constraintltem cil = new ConstraintItem( taul, tau2
Constraintltem ci2 = new ConstraintItem(tau2, taul)
csl = csl .Union (cs2 .Append (cil .Append (ci2)
.
.
)
)
)
}
}
+
)
(
return csl
;
}
/*
void InstanceOf Expression
(
)
:
{}
{
RelationalExpression
(
)
[
"instanceof" Type
}
*/
50
(
)
]
]
Triple RelationalExpression (Gamma gamma)
{
Triple csl;
Triple cs2 = null;
csl = ShiftExpression (gamma)
Shif tExpression (gamma)
(
"<"
(
"<="
">"
|
|
">="
)
|
cs2
{
if (cs2
!=
null)
{
String taul = csl getType ()
String tau2 = cs2 getType ()
Constraintltem cil = new Constraintltem taul tau2
Constraintltem ci2 = new Constraintltem tau2 taul
csl = csl .Union (cs2 .Append (cil) .Append (ci2)
.
.
(
,
)
(
,
)
;
)
return csl;
!
Triple Shif tExpression Gamma gamma)
(
:
{
Triple csl;
Triple cs2 = null;
}
{
csl = AdditiveExpression (gamma)
AdditiveExpression (gamma
(
"<<"
(
">>"
|
|
">»"
{
if (cs2
!=
null)
String taul = csl getType ()
String tau2 = cs2 getType ()
Constraintltem cil = new Constraintltem (taul tau2
Constraintltem ci2 = new ConstraintItem( tau2, taul)
csl = csl .Union (cs2 .Append cil .Append (ci2
.
.
,
)
(
)
)*
{
return csl
}
51
)
)
)
cs2 =
Triple AdditiveExpression (Gamma gamma)
:
{
Triple csl;
Triple cs2 = null;
)
{
csl - MultiplicativeExpression (gamma)
MultiplicativeExpression (gamma)
(
(
"-"
"+"
cs2 =
)
|
{
if (cs2
!= null)
String taul = csl getType ()
String tau2 = cs2 getType ()
Constraintltem cil = new Constraintltem taul tau2
Constraintltem ci2 = new Constraintltem (tau2, taul
csl = csl Union (cs2 .Append (cil .Append ci2
.
.
,
(
.
)
)
(
)
)
)
return csl;
Triple MultiplicativeExpression (Gamma gamma
{
Triple csl;
Triple cs2 = null;
csl = UnaryExpression (gamma)
UnaryExpression (gamma)
(
(
"-"
"/"
"+ "
I
)
|
cs2 =
{
if (cs2
!= null)
String taul = csl getType ()
String tau2 = cs2 getType ()
Constraintltem cil = new Constraintltem taul tau2
Constraintltem ci2 = new Constraintltemf tau2 taul
csl = csl .Union (cs2 .Append (cil .Append (ci2
.
.
(
)
)
{
return csl;
52
)
,
)
,
)
Triple UnaryExpression (Gamma gamma)
{Triple cs;
:
{
((
"-"
"+"
cs = UnaryExpression (gamma
)
|
I
/*
PrelncrementExpression
(
PreDecrementExpression
(
I
I
*/
cs = UnaryExpressionNotPlusMinus (gamma)
return cs;
)
{
}
/*
void PrelncrementExpression
{
(
)
:
(
)
:
)
{
"++" PrimaryExpression
(
)
}
void PreDecrementExpression
{}
{
"--" PrimaryExpression))
}
*/
Triple UnaryExpressionNotPlusMinus (Gamma gamma)
{Triple cs;
{
((
"~"
"!"
I
cs = UnaryExpression (gamma)
)
I
/*
LOOKAHEAD( CastLookahead
CastExpression
(
)
)
(
I
*/
cs = Postf ixExpression (gamma)
return cs ;
)
{
53
/*
// This production is to determine lookahead only.
The LOOKAHEAD
// specifications below are not used, but they are there just to
// indicate that we know about this,
void CastLookahead
(
LOOKAHEAD 2
"(" PrimitiveType
:
)
(
LOOKAHEAD
"
" Name
(
Name
(
"
"
it
(
r
(
T1
M
1
Tl
(
"("
new"
")"
Named
|
Literal
()
"<"
"~"
(
I
"("
I
<IDENTIFIER>
I
|
"this"
)
*/
Triple Postf ixExpression (Gamma gamma)
Triple cs
:
;
cs = PrimaryExpression (gamma)
return cs;
//[
"--"
"++"
|
]
{
/*
void CastExpression
)
:
()
(
(
}
(
LOOKAHEAD
(
2
"(" PrimitiveType
"("
Named
(
"["
"]"
)*
")" UnaryExpression
(
"[" "]" )* ")" UnaryExpressionNotPlusMinus
*/
Triple PrimaryExpression (Gamma gamma)
Triple cs = null;}
cs = PrimaryPrefix (gamma)
{
//
(
:
PrimarySuf fix (gamma)
return cs;
54
)*
|
"super"
Triple PrimaryPref ix Gamma gamma)
:
(
{
Triple cs = null;
Triple csl = null;
Triple cs2 = null;
String id = null;
Gamma temp = null;
]
{
(
cs = Literal
(
)
I
["this" "."]
Named
id =
{
Gammaltem item = gamma FindType id)
.
(
if (item != null)
String mod = item. getModif ier
mod. equals (""))
if (mod. equals "var"
II
String tau = item. getType
String alpha = sg NextSymbol
Constraintltem cxl = new ConstraintItem( tau, alpha
cs = new Triple cil alpha ,"")
(
)
(
)
(
)
.
(
)
)
,
(
}
else if (mod. equals "proc" ))
temp = item. getParam
(
(
)
i
i
else
System. err println "Secure Parse failed");
System. exit
//end if
{
(
.
(
)
J
}
else
System. out println "Undefined variable: " + id);
System. exit 0)
temp = new Gamma "temp" .Append (new Gammaltem ("", sg, ""))
}//end if
{
(
.
//
(
(
)
}
[
"("
[
csl = PrimaryPref ix (gamma)
{
//create constraint type (csl) = type (param)
String tauPrime = csl getType ()
String taul =
(Gammaltem) temp getFromList ()). getType ()
temp removeFromList
Constraintltem cil = new Constraintltem (taul tauPrime)
Constraintltem ci2 = new Constraintltem (tauPrime, taul
.
(
.
.
(
)
,
)
//add constraint to csl
csl = csl .Append (cil) .Append (ci2)
cs = csl;
}
(
"," cs2 - PrimaryPref ix (gamma)
{
//create constraint type(cs2) - type (param)
String tauDoublePrime = cs2 getType ()
String tau2 =
(Gammaltem) temp getFromList ()). getType ()
temp. removeFromList
Constraintltem ci3 = new Constraintltem tau2 tauDoublePrime)
.
(
.
(
)
(
55
,
Constraintltem ci4
=
//csl Union cs2
csl = csl .Union (cs2
new Constraintltem tauDoublePrime, tau2
(
)
//add constraint to csl
csl = csl .Append ci3) .Append (ci4
c s = csl;
(
)
)
)
/
*
]
"
"
)
1
+
I
"this"
I
"super" "." <IDENTIFIER>
*/
I
")"
"(" cs = Expression (gamma)
/*
I
AllocationExpression
(
*/
)
{
return cs
;
}
/*
Triple PrimarySuf f ix
(
)
:
{}
{
"
["
Expression
()
"J
I
"." <IDENTIFIER>
I
Arguments
(
}
*/
String PrimaryLeftExpression
(
)
:
{}
{
" ("
"this" "."
{return token. image;
[
]
[
]
Named
[
") "
56
]
)
Triple Literal
{
(
:
)
)
{
(
<INTEGER_LITERAL>
I
<FLOATING_POINT_LITERAL>
I
<CHARACTER_LITERAL>
I
<STRING_LITERAL>
I
BooleanLiteral
(
I
NullLiteral
{return new Triple sg NextSymbol (),""
(
)
)
.
(
}
void BooleanLiteral
{
(
:
)
}
{
"true"
I
"false"
}
void NullLiteral
(
)
:
{}
f
"null"
}
/*
void Arguments
"("
[
(
)
:
ArgumentList
(
)
]
")"
}
Triple ArgumentList (Gamma gamma)
{
:
}
{
Expression
(
)
(
"," Expression
()
)
}
^7
)
;
void AllocationExpression
L00KAHEAD(2)
"new" PrimitiveType
(
ArrayDimensions
)
(
I
"new" Name
(
Arguments
(
)
(
)
ArrayDimensions
I
(
)
)
}
V
LOOKAHEAD specification below is to parse to
PrimarySuf f ixif there is an expression between the "[...]".
/* The second
*
+
/
/*
void ArrayDimensions
{
(
)
:
}
!
(
LOOKAHEAD
"
(2)
[
"
Expression
()
"]"
}
*/
/*
+
Statement syntax follows.
*/
Triple Statement (Gamma gamma)
(Triple cs = null;}
:
{
(LOOKAHEAD
(2)
/*
LabeledStatement
(
/
cs - Block (gamma)
cs = EmptyStatement (gamma)
cs = StatementExpression (gamma)
SwitchStatement
"
;
(
/
cs = If Statement gamma
(
cs = WhileStatement (gamma)
cs = DoStatement (gamma)
ForStatement
(
BreakStatement
(
ContinueStatement
ReturnStatement
(
(
58
)+
(
LOOKAHEAD
(2)
"[" "]"
p
ThrowStatement
(
Synch roni zeds tat ement
TryStatement
(
7
)
{
return cs;
/*
void LabeledStatement
{
(
)
:
1
{
<IDENTIFIER> ":" Statement
(
}
*/
Triple Block (Gamma gamma)
{Triple cs;
:
{
"{" cs = BlockStatementList (gamma)
{
return cs
"}"
;
Triple BlockStatementList (Gamma gamma)
{
Triple csl = null;
Triple cs2;
}
I
(
L00KAHEAD(2)
cs2 = BlcckStatement gamma
(
r
i
if (cs2 != null)
if (csl == null)
csl = cs2;
{
{
)
else
String taul = csl getType ()
String tau2 = cs2 getType ()
Constraintltem cil = new Constraintltem taul, tau2)
Constraintltem ci2 = new Constraintltem tau2 taul
csl = csl Union (cs2
csl = csl .Append cil
csl = csl .Append (ci2
}//end if
}//end if
{
.
.
(
(
.
)
(
)
;
)
;
return csl;
59
,
)
Triple Blocks tatement (Gamma gamma)
{Triple cs;
:
{
LOO KAHEAD (Type
<IDENTIFIER>
cs = LetvarStatement (gamma
(
(
)
I
cs = Statement (gamma
return cs;
)
{
}
Triple LetvarStatement (Gamma gamma)
{
Dual d;
Triple cs = null;
}
{
d = LocalVariableDeclaration (gamma!
gamma = d gamma ;
cs = BlockStatementList (gamma)
{
.
{
if (cs != null)
cs .Union (d. cs ;
cs setModif ier "cmd"
)
(
.
)
}
else
{
cs = d. cs
}
return cs;
Dual LocalVariableDeclaration (Gamma gamma)
{Dual d;
:
{
Type
(
d = VariableDeclarator (gamma)
"," VariableDeclarator (gamma)
(
{
)*
return d;
}
Triple EmptyS tatement (Gamma gamma)
:
{}
{
IT
.
It
f
{return new Triple (sg.NextSymbol
(),
60
"cmd"
);
Triple StatementExpression (Gamma gamma)
/
:
+
+
The last expansion of this production accepts more than the legal
Java expansions for StatementExpression.
*
V
{
Triple cs
;
{
(
LOOKAHEAD
(
PrimaryExpression gamma
AssignmentOperator (gamma)
)
(
cs = Assignment (gamma)
I
cs = Postf ixExpression (gamma
return cs ;
)
)
{
}
/*
void SwitchStatement
(
)
:
{)
{
"switch" "(" Expression () ")" "{"
BlockStatement
SwitchLabel
(
(
(
)
+
(
"}"
}
void SwitchLabel
(
)
:
{)
{
"case" Expression
()
":"
I
"default" ":"
)
*/
61
)
)
)*
)
Triple If Statement (Gamma gamma)
:
/*
The disambiguating algorithm of JavaCC automatically binds dangling
else's to the innermost if statement.
The LOOKAHEAD specification
is to tell JavaCC that we know what we are doing.
*
*
*
*/
{
Triple cs;
Triple csl;
Triple cs2 = null;
"if" "(" cs = Expression (gamma) ")"
csl = Statement (gamma)
LOOKAHEAD(l) "else" cs2 = Statement (gamma)
[
]
{
String tau = cs getType
String taul = csl getType ()
String alpha = sg NextSymbol
Constraintltem cil = new ConstraintI tern tau, taul
Constraintltem ci2 = new Constraintltem (taul, tau)
Constraintltem ci3 = new Constraintltemfalpha, tau)
cs = cs Union (csl .Append (cil .Append ci2 .Append (ci3
cs setType (alpha
cs setModif ier "cmd"
(
.
)
.
.
(
)
(
.
)
.
(
)
)
)
)
)
(
.
if (cs2
)
!= null)
String tau2 = cs2 getType ()
Constraintltem ci4 = new ConstraintItem( tau, tau2
Constraintltem ci5 = new ConstraintItem( tau2, tau)
Constraintltem ci6 = new ConstraintItem( taul, tau2
Constraintltem ci7 = new Constraintltem (tau2 taul
.
)
,
)
)
cs =
cs .Union (cs2) .Append(ci4) .Append(ci5) .Append(ci6) .Append(ci7)
}//end if
return cs;
62
Triple WhileStatement (Gamma gamma)
{
Triple csl = null;
Triple cs2 = null;
"while" "(" csl - Expression (gamma
)
")" cs2 = Statement (gamma
]
{
String tau = csl getType ()
String tauPrime = cs2 getType ()
String alpha = sg NextSymbol ()
Constraintltem cil = new Constraintltem (tau, tauPrime
Constraintltem ci2 = new Constraintltem tauPrime, tau)
Constraintltem ci3 = new Constraintltem (alpha, tau)
csl = csl .Union (cs2 .Append cil .Append ci2 .Append (ci3)
csl setType (alpha
csl setModif ier "cmd"
return csl;
.
.
.
)
;
(
)
.
(
)
(
)
)
(
.
)
;
Triple DoStatement (Gamma gamma;
{
Triple csl = null;
Triple cs2 = null;
I
"do" cs2 = Statement (gamma)
"while" "(" csl = Expression (gamma!
String tau = csl getType ()
String tauPrime = cs2 getType ()
String alpha = sg. NextSymbol ()
Constraintltem cil = new Constraintltem tau, tauPrime)
Constraintltem ci2 = new ConstraintItem( tauPrime, tau)
Constraintltem ci3 = new Constraintltem (alpha, tau)
csl = csl .Union cs2 .Append (cil .Append (ci2 .Append (ci3)
csl setType (alpha)
csl setModif ier "cmd")
return csl;
.
.
(
)
(
)
.
(
.
i
/*
void ForStatement
(
)
:
U
{
"for" "("
[
ForlnitO
[
Expression
]
ForUpdateO
]
Statement
63
)
void Forlnit
(
:
)
LOOKAHEAD( Type
<TDENTIFIER>
LocalVariableDeclaration
(
)
)
(
StatementExpressionList
(
void StatementExpressionList
StatementExpression
void ForUpdate
(
)
(
:
StatementExpressionList
void BreakStatement
"break"
(
void ContinueStatement
"continue"
[
(
:
)
< IDENTIFIED
[
:
)
"," StatementExpression
(
)
(
(
]
)
:
<IDENTIFIER>
void ReturnStatement
(
";"
]
:
)
}
"return"
[
Expression
void ThrowStatement
(
"throw" Expression
)
(
)
]
:
()
void SynchronizedStatement
(
)
:
"synchronized" "(" Expression
(
)
")" Block
}
64
void TryStatement
(
"try"
Block ()
"catch" "(" FormalParameter
"finally" Block
(
[
(
)
(
)
")" Block
]
7
65
()
)
66
APPENDIX B - STATIC ANALYZER SOURCE
CODE
67
File: Gamma. Java
Date: 24 Feb 98
//
//
//
//
//
//
//
Author: LT James
Purpose:
D.
Harvey, USN
Developed as part of
Basically
analyzer.
a
a
package thesis;
import java.io.*;
public class Gamma
i
protected Object ob j
protected Gamma next;
protected Gamma rear = null;
public String name;
;
public Gamma (String name)
{
this.obj = null;
this. next = this;
this. name = name;
if rear == null
rear = this;
(
private Gamma
(
{
this.obj = null;
this. next = this;
public Object getFromList
(
{
return this.obj;
]
public Gamma removeFromList
(
{
return this. next;
public synchronized boolean isEmpty
{
if (this == rear)
return true;
else
return false;
68
secure information flow static
linked list.
public Gamma Append (Gamma Item gi
{
Gamma g = new Gamma
g.obj = gi;
g.next = this;
retur n g
(
)
public Gammaltem FindType String name)
(
Gammaltem temp = null;
Gamma list = this;
boolean matchFound = false;
do{
ifilist.obj == null)
return null;
String item =
((
Gammaltem) list obj
.
if item. equals (name
temp = (Gammaltem) list obj
matchFound = true;
(
)
)
.
}
else
list = Gamma list next
}//end if
while matchFound)
(
)
(
j
(
.
;
!
return temp;
public String toString()
{
if (isEmpty
return "";
(
)
else
return (this obj
.
+
""
+
this. next);
i
}//end gamma class
69
).
Name;
/
/**±ir + ** + * + ** + ± + + + ic**ir + + + + * + + irieir + + ** + + + + + ± + + **+ + ic + + + + + + + +
File:
Date:
//
//
//
//
//
//
//
//
//
-)r-)r
+ -k + + -1rie-k-)c-k-ir +
Gammal tern. Java
24 Feb 98
Author:
Purpose:
LT James D. Harvey, USN
Developed as part of a secure information flow static
It is an item to be placed into gamma. The
analyzer.
structure consists of a name and a type. The type may
consist of 1-3 fields.
package thesis;
import java.io.
+
;
public class Gamma I tern
{
protected String Name;
protected String Type;
protected String Modifier;
private Gamma param;
public GammaItem(String Name, SymbolGenerator sg, String mod)
{
this. Name = Name;
this. Type = sg NextSymbol
this .Modifier = mod;
.
(
)
1
public Gammaltem( String Name, String Type, String mod)
{
this. Name = Name;
this. Type = Type;
this .Modi fier = mod;
public void set Param (Gamma gammal
this. param = gamma;
public Gamma getParamf)
{
return this. pa ram;
public String getName
{
return this. Name;
public String getType
(
{
return this. Type;
}
70
public String getModif ier
(
{
return this .Modifier
)
public String toString()
{
if (Modifier equals "proc"
return ("("+ Name +":"+ Type + Modifier +"("+ param +")"+")");
(
.
)
)
{
)
elsel
]
return
//end if
(
"(" + Name + ":" + Type +
}
//end class
71
Modifier
+
")"
);
// + + * + + + + ** + + + + +
+ + + + + + + + + + ++ + + * + + + + + * + * + * + * + + + + + + + + + + + + + + + + + + + * +
*+ + + ++*
File: Triple. Java
Date: 24 Feb 98
II
//
//
//
//
//
//
//
//
Author: LT James
Purpose:
Harvey, USN
D.
Developed as part of a secure information flow static
analyzer.
The structure consists of a constraint set
The type may consist of 1-2
and a principle type.
fields.
//****** + * + + + *** + ** + ** + + + + ** + ** + ** + + *** + + *** + + + * + * + * + + + + + + * + + + *** + »-**•*•-*-
package thesis;
public class Triple
{
private LinkedList ConstraintSet
private String Type;
private String TypeModif ier
public Triple
(
)
(
this. Type = "Type";
this .TypeModif ier = "mod";
ConstraintSet = new LinkedList "name"
(
)
public Triple (Constraintltem ci, String Type, String Modifier;
{
ConstraintSet = new LinkedList "name"
this. Type = Type;
this TypeModif ier = Modifier;
ConstraintSet = ConstraintSet addToList (ci
(
)
.
.
)
public Triple (LinkedList ConstraintSet, String Type, String Modifier)
{
this. Type = Type;
this .TypeModif ier = Modifier;
this ConstraintSet = ConstraintSet;
.
}
public Triple (String Type, String Modifier)
{
this. Type = Type;
this. TypeModif ier = Modifier;
ConstraintSet = new LinkedList "name"
(
]
public String getType
(
{
return this. Type;
)
72
)
public String getModif ier
(
<
return this TypeModif ier
.
public void setModif ier (String Modifier)
{
this TypeModif ier - Modifier;
.
i
i
public void setType (String type)
{
this. Type = type;
)
public Triple Union (Triple setTwo)
{
LinkedList temp = this ConstraintSet
(Constraintltem) temp. obj == null){
return new Triple (setTwo ConstraintSet this Type,
this TypeModif ier
.
if
(
,
.
.
.
]
while (temp next obj
temp = temp. next;
.
.
null){
!=
temp. next = setTwo ConstraintSet
this ConstraintSet rear = setTwo ConstraintSet rear
return new Triple (this. ConstraintSet, this. Type, this. TypeModif ier
.
.
.
.
.
public Triple Append (Constraintltem
)
C)
!
return new Triple this ConstraintSet addToList
(
.
.
this. Type,
this .TvpeModif ier
(C)
,
)
1
public String toString()
{
return ("{"+" ["+ ConstraintSet +"]"+","+ Type
i
;
i
//end class
73
+
TypeModifier +"]"
);
// + + + + + +
4-
+ + ^4. + + + + + + + + + + + + + +
^* + +
+ + + +
*+
+ +
4-
+ + + + + + + + + +
4-
++ ++ + *+
4-->-
+
-*-
+
*+
+ *,l.*-l-*
File: Constraintltem. Java
Date: 24 Feb 98
//
//
//
//
//
//
//
Author: LT James D. Harvey, USN
Purpose:
Developed as part of a secure information flow static
The structure consists two types.
analyzer.
package thesis;
public class Constraintltem
r
i
protected String Typel;
protected String Type2;
public ConstraintItem(String Typel, String Type2
!
this. Typel = Typel;
this.Type2 = Type2;
public String toString
(
(
return
(
"(" + Typel + "," + Type2 + ")"
}
i
74
);
File:
Date:
//
//
//
//
//
//
//
LinkedList Java
.
24
Feb 96
Author: LT James
Purpose:
D.
Harvey, USN
Developed as part of a secure information flow static
analyzer.
package thesis;
public class LinkedList
f
protected Object ob j
protected LinkedList next;
protected LinkedList rear - null;
public String name;
;
public LinkedList String name)
(
i
i
this.obj = null;
this. next = this;
this. name = name;
if (rear == null)
rear = this;
private LinkedList
i
this.obj = null;
this. next = this;
public LinkedList addToList (Ob ject
{
LinkedList
1
=
new LinkedList
(
)
ob j = o;
l.next = this;
1
.
return
1;
public Object getFromList
(
return this.obj;
public LinkedList remove FromList
(
return this. next;
75
o]
public synchronized boolean isEmptyO
{
if (this == rear)
return true;
else
return false;
public String toString
(
{
if (isEmpty
(
)
return "";
else
return this obj +
(
.
"
"
+
this. next);
i
//end class
76
File: SyrnbolGenetator Java
Date: 24 Feb 9 8
//
//
//
//
//
//
//
.
Author: LT James
Purpose:
D.
Harvey,
USN
Developed as part of a secure information flow static
analyzer. Generates new type variables
package thesis;
import
j
ava io
.
+
;
public class SymbolGenerator
{
private int counter = 0;
private static String TAU
= "tau";
public synchronized String NextSymbol
(
f
String Symbol = TAU
counter++;
return Symbol;
+
counter;
public static void main (String
[]
args)
;
i
SymbolGenerator sg = new SymbolGenerator
for (int i = 0; i < 10; i++)
System. out .print In (sg. NextSymbol
i
j
}
}
//end class
77
(
)
)
// + + ±* + + + + + ± + + ± + + + ± + ± + + + + ± + + + + * + ± + ±± + ±± + + + + ± + + + + + + + + + + + + ± + + + ± + + +
File:
Date:
II
//
//
//
//
//
//
SyrobolGenetator
2 4 Feb 9 8
Author: LT James
Purpose:
// + ± +
D.
.
j
-)r-k-)r->r
+ ++
ava
Harvey, USN
Developed as part of a secure information flow static
analyzer. A data structure
++ + + + * + + + + + + + + ± + + + + + + + + + + + ± + ± + + + + ± + ±+ + + + + + + + + + + + + + + * + + + ±±±-tr + -)r-*-+-±
package thesis;
public class Dual
{
public Triple cs;
public Gamma gamma;
public String id;
public Dual (Triple cs, Gamma gamma)
{
_ ,-,_ ..
_„
— wo
t-iiXo.wo
4-v.
.:
,
,
this. gamma = gamma;
78
APPENDIX C - TEST PROGRAMS
7')
// + + + + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + *
File: test. Java
Date: 24 Feb 98
//
//
//
//
//
//
//
Author: LT James
D.
Harvey, USN
Developed as part of a secure information flow static
analyzer.
+ ++
// + + + ± + + + + + + + + + + + + + + ±±±± + + + + + + + + ± + + + + + + + + + + ± + + + + + + + ± + ± + + + + + + + +
class test
Purpose:
-k-k-)r
-lr
{
public static void pl(int
x,
int
y)
{
y = x;
The output of the
static
analyzer on the above program produced the following results:
Constraint
set: {13
Gamma:
Results show, with
x: x () var
pi
and
y:
<
:
T2, T2
=
x^proc
Xi, to
<
(x var,
iivar, that Xo
<
12}
Xivar)
Xi.
This
is
what we would expect
ensure secure flow since the program assigns the value of x to y.
80
to
// + + + + + + + +
*-
+ * + + **- +
** + *7k- + + + + +
+ +++ +++ + + + + ++ + *+ +++ +++*+++++ +++ + + + + + + + + + + + +
File: test. Java
Date: 24 Feb 98
//
//
//
//
//
//
//
Author: LT James
D.
Harvey, USN
Developed as part of
analyzer.
Purpose:
// + + + + * + + + + + + + + + + + + + +
a
secure information flow static
+ + + + + + + + + * + + + + + + + + + + + + + + + + + + + + + + * + + + + + + + + + + + + +
*-
+
class test
{
public static void pl(int
x,
int
y)
{
if
x ==
y = 0;
(
)
else
y - 1;
The output of the
static
analyzer on the above program produced the following results:
Constraint
set:
{17
Xo
Gamma:
=
<
pi
X5, 17
X 2 T5
,
.
=
<
i:, Xs
X4
,
14
<
=
Xsproc (Xovar,
X2, X5
Xi, x 7
=
<
iivar)
=
X2, X3
x6 , X 6
=
X2,
Xi
}
// + * + +
++ + +
**
+ + + * ++ +++ +*+++++ ++++++ + +++++++++++ +
*•
+ ++
•*•
+
*-*-
+
*•
+
*•
File: test. Java
//
Date: 24 Feb 98
//
//
Author: LT James D. Harvey, USN
//
//
Purpose:
Developed as part of a secure information
//
flow static analyzer.
//
//** + ** + + + + + + + * + + + * + + + + + + + + * + + + + + + + • + + + + + + + + + + *-* + + + + + + + *-*--*•
*•
class test
{
public static void pl(int
x,
int
y)
{
int a = x;
int b = 0;
while
(a
>
0)
b = b + 1;
a = a - 1
}
y = b;
The output of the
Constraint
set:
static
= in, Xi2< U,
{ii 4
18
<
TlO
analyzer on the above program produced the following results:
T 6 , T6
=
=
19, X2
13. 17
<
=
T9, Tl4
is
= U,
16. T3
<
x?
<
Tl3, Tl
=
T 6 T]
.
=
Gamma =
pi:
A
of the analysis of this program
partial trace
Ti 2
X4,
i
X2
<
< U, in =
T9 T9
Tl3, 13
.
<
=
T2
Tl3, to
is,
,
<
X2
proc(iovar, iivar)
82
is
shown
in
Chapter VI.
// + + + + + + + + + + + + + + + + + + + * + + * + + + + +
•*-
+ +
-*-
++
-*•*-•*•*
++++
*-
+
•*•
+ + + + + + * + *•*•*
File: test. Java
//
Date: 24 Feb 98
//
//
Author: LT James D. Harvey, USN
//
//
Purpose:
Developed as part of a secure information
//
flow static analyzer.
//
//** + + + + + *** + * + + ******** + + + + *** + + + ** + + * + + + + * + ** + + **•* + + *•* + *
class test
{
public static void pl(int
x,
int
a,
int b)
y)
{
int a = x;
int b = 0;
while
(a
>
0)
b = b + 1;
a = a - 1
}
y = b;
)
public static void p2(int
{
a = a + 4 ;
b = b + 2;
if
}
>
(a
b)
{
pl(b,a)
else
pi a b
(
,
)
;
;
}
b = a + b;
}
public static void main
(
{
int
int
s
- 1;
t
= 8;
do{
p2(2,t)
t = t }
while
(t
;
1;
>
3)
83
The output of the
1
The
First
static
analyzer on the above program produced the following
procedure, p
Constraint
1 ,
produces:
set:
{xh =
18
Gamma:
Gamma:
3.
The
—
X9, 1 2
=
t3 5 1 7
<
X 9 , X14
=
14, 15
=
16, 13 5: 16, Xl
<
X13, T13
<
T4, 12
=
1
S
Ii, I3
<
Gamma:
is
=
i6,
T2,
<
T13, To
1:1
iivar)
p2, produces:
set:
{
=
X30
= in,
X17, I29
= in,
X20
<
X19
in,
in =
X15,
Xl8
=
X17, X15
<
X17, T22
<
X20, X20
Xi6, X21
=
X20,
Xl6
—
X20, X27
=
X25, X27
=
X23, X29 5: X23, T25
=
X23,
X24
—
X23, X15
<
X23, Xi6
<
X24, X26
Xl6
<
X25, X15
<
126, X28
=
Xo, X27
X32
<
X30, X30
=
Xi6, X31
=
X30, X15
p2
pi
:
:
set: {142
inproc
(Xi.war,
Xnproc
(Xovar,
x^var)
=
—
=
Xo, X25
Xo, X15
<
<
=
x4 o, X35
,
iivar)
=
X40, x 4 i
x 4 o, X34
<
x 4o,
=
X35, I36
-
Xl5, X35
=
X15, X34
<
X36,
X39
—
X37, T37
=
T34, I38
=
X37, T34
<
T37
main
:
:
:
i42proc
(
)
xn proc a iisvar, b x ]6 var),
xnproc (x:x var, y:T]Var)
:
(
updated with each procedure.
84
:
=
<
X30, Xi6
X37
p2
pi
Gamma
=
14, 19
19, 19
third procedure, main, produces:
Constraint
4.
16
14, i6
pi: xnproc dovar,
The second procedure,
Constraint
=
<
I12, T12
5: 16,
XlO
2.
results:
}
Xo,
X27, X16
<
X31
}
<
128,
INITIAL DISTRIBUTION LIST
Defense Technical Information Center
8725 John J Kingman Road. Suite 0944
Fort Belvoir.
VA 22060
Dudley Knox Library
Naval Postgraduate School
4
1
1
Dyer Road
Monterey,
3.
CA
93940
Dan Boger, Chairman. Code CS.
Computer Science Department
Dr.
Naval Postgraduate School
Monterey, CA 93940
Dr. Dennis Volpano,
Code CS/Vd.
Computer Science Department
Naval Postgraduate School
Monterey,
CA 93940
Dr Craig Rasmussen, Code
Department of Mathematics
Naval Postgraduate School
Monterey, CA 93940
6
LT James D Harvey
7090 Brook Dr.
Morrow, OH 45152
MA/Ra
DUDLEY KNOX LIBRARY
NAVAL POSTGRADUATE SCHOOL
MONTEREY CA 93943-5101
12
4
T
G
31511:
10/99 22527-200
nulb
||