Thread: [Clirr-devel] Java doesn't appear to do runtime checks for class/method access rights
Status: Alpha
Brought to you by:
lkuehne
From: Simon K. <si...@ec...> - 2004-07-05 07:39:39
Attachments:
access.tar.gz
|
Hi Lars, Could you please check that I haven't gone completely mad? Attached is an archive which contains some java code that appears to demonstrate that the Java JVM/runtime does not check for class or method access rights. Try: * cd v1; javac Foo.java * cd v2; javac Foo.java * cd .. * cp v1/Foo.class pkg * javac Main.java * java Main --> so far, all as expected. But now: * cp v2/Foo.class pkg * java Main --> the main class successfully invokes a private method on the package-scope Foo class! The java lang spec document seems clear that this *should* throw an IllegalAccessError, but it doesn't. I would like someone to confirm that I am not having hallucinations here before I add a note about this to the message description document. I've tried this with: * sun java 1.3 on AIX * sun java 1.4 on linux * sun java 1.5 on linux * IBM java 1.4 on AIX * IBM java 1.4 on linux and they all give the same result. Regards, Simon |
From: <lak...@t-...> - 2004-07-05 18:03:58
|
Simon Kitching wrote: >Hi Lars, > >Could you please check that I haven't gone completely mad? > >Attached is an archive which contains some java code that appears to >demonstrate that the Java JVM/runtime does not check for class or method >access rights. > >Try: >* cd v1; javac Foo.java >* cd v2; javac Foo.java >* cd .. >* cp v1/Foo.class pkg >* javac Main.java >* java Main >--> so far, all as expected. > >But now: >* cp v2/Foo.class pkg >* java Main >--> the main class successfully invokes a private method on > the package-scope Foo class! > >The java lang spec document seems clear that this *should* throw an >IllegalAccessError, but it doesn't. I would like someone to confirm that >I am not having hallucinations here before I add a note about this to >the message description document. > >I've tried this with: >* sun java 1.3 on AIX >* sun java 1.4 on linux >* sun java 1.5 on linux >* IBM java 1.4 on AIX >* IBM java 1.4 on linux >and they all give the same result. > >Regards, > >Simon > > I can confirm your results: access> java Main public method f1 of package scope class Foo called! private method f2 of package scope class Foo called! Wow!! This is scary, but on the other hand it's quite logical. Try to disassemble the code of Main: access> javap -private -c Main Compiled from "Main.java" public class Main extends java.lang.Object{ public Main(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: new #2; //class pkg/Foo 3: dup 4: invokespecial #3; //Method pkg/Foo."<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #4; //Method pkg/Foo.f1:()V 12: aload_1 13: invokevirtual #5; //Method pkg/Foo.f2:()V 16: return } It seems the bytecode for both method calls is the same. The Main class simply seems to have no record whether the called methods are private or public, so the VM can't check anything... ? I couldn't find the IllegalAccessError requirement you mentioned, but in $13.4.6 the JLS says: "Changing the declared access of a member or constructor to permit less access may break compatibility with pre-existing binaries, causing a linkage error to be thrown when these binaries are resolved. Less access is permitted if the access modifier is changed from default access to |private| access; from |protected| access to default or |private| access; or from |public| access to |protected|, default, or |private| access" Not quite sure what to make of this, to me the spec is quite confusing - aren't those two sentences contradicting each other? Still surprised, Lars |
From: Simon K. <si...@ec...> - 2004-07-05 23:23:47
|
On Tue, 2004-07-06 at 06:06, Lars K=FChne wrote: > Simon Kitching wrote: > >Attached is an archive which contains some java code that appears to > >demonstrate that the Java JVM/runtime does not check for class or meth= od > >access rights. > > > >The java lang spec document seems clear that this *should* throw an > >IllegalAccessError, but it doesn't. I would like someone to confirm th= at > >I am not having hallucinations here before I add a note about this to > >the message description document. > > > I can confirm your results: >=20 > access> java Main > public method f1 of package scope class Foo called! > private method f2 of package scope class Foo called! >=20 > Wow!! >=20 > This is scary, but on the other hand it's quite logical. Try to=20 > disassemble the code of Main: [...] > It seems the bytecode for both method calls is the same. The Main class= =20 > simply seems to have no record whether the called methods are private o= r=20 > public, so the VM can't check anything... ? The information must be in the class file somewhere, because in BCEL we can ask: somemethod.isPrivate() etc. Also, when compiling source with javac against a library the compiler can report attempted calls to inaccessable methods. >=20 > I couldn't find the IllegalAccessError requirement you mentioned, but i= n=20 > $13.4.6 the JLS says: >=20 > "Changing the declared access of a member or constructor to permit less= =20 > access may break compatibility with pre-existing binaries, causing a=20 > linkage error to be thrown when these binaries are resolved. >=20 > Less access is permitted if the access modifier is changed from default= =20 > access to |private| access; from |protected| access to default or=20 > |private| access; or from |public| access to |protected|, default, or=20 > |private| access" >=20 > Not quite sure what to make of this, to me the spec is quite confusing = -=20 > aren't those two sentences contradicting each other? The sentence beginning "Less access" *is* poorly worded, but correct.=20 To rephrase:=20 "<em>Less</em> access is permitted if ..." or: "The access permissions are defined to be 'less' if the access =20 modifier is changed from...."=20 The sentence starting "Changing..." says what happens if a change resulting in "less access" is made: a linkage error is thrown. Hmm..I can't find the bit that specifies "IllegalAccessError" either, though I'm sure this *is* the exception that should be thrown. >=20 > Still surprised, Me too. And I think that clirr still should report an ERROR here, because this change is a violation of the spec, even if it isn't currently enforced by either Sun or IBM JVMs. What do you think? Cheers, Simon |