On 09/03/2013 07:26 PM, Nick Williams wrote:
On Sep 3, 2013, at 12:16 PM, Peter Levart wrote:

On 09/03/2013 04:39 PM, Nick Williams wrote:
Do you mean sun.reflect.CallerSensitive can go away?  This is very important 
part of the design that we need to detect which methods are caller-sensitive.   
I keep seeing you suggest this and it is unclear to me if you only mean to 
remove java.lang.@CallerSensitive in your proposal.

Yes, that's what I mean. If you carefully examine the (existing) native code 
that backs getCallerClass, you see that @CallerSensitive is /only/ used as an 
enforcement mechanism. When I first read about @CallerSensitive, I /thought/
  you could take a call stack like this one:

@CallerSensitive getCallerClass()
@CallerSensitive someMethod1()
@CallerSensitive someMethod2()
@CallerSensitive someMethod3()
@CallerSensitive someMethod4()
actualCallerMethod()

And calling getCallerClass would return the class for actualCallerMethod(). 
However, I was wrong. getCallerClass
/always/ returns someMethod1(). @CallerSensitive is /not/ used to determine 
when to stop looking for the caller. It's just an enforcement mechanism to 
ensure that only built-in JVM classes can call getCallerClass.
*AND* that Reflection.getCallerClass() can only be called from within methods 
annotated with @CallerSensitive.
That's exactly what I said, just worded differently.

Now for that part, the public API equivalent (StackTraceFrame.getCallerClass() 
or whatever it is called) need not be restricted to methods annotated with any 
annotation, but that means that this public API should not be used to implement 
security decisions since MethodHandles API allows caller to be spoofed unless 
looking-up a method annotated with @CallerSensitive...

  This is /not/ how I did it, this is how it already was. Because of this, you 
could delete the @CallerSensitive annotation completely and getCallerClass 
still be fully functional the way it is. It just wouldn't be restricted to 
annotated methods anymore.
For security unrelated things (like logging and similar) public API need not 
include any enabling annotation, but it needs to be documented that it should 
not be used for security decisions.
Now that's a change that makes sense and would certainly be more user-friendly. 
Keep @CallerSensitive private, but don't require it for 
StackTraceFrame#getCallerClass()/getCallerFrame(). Document that 
StackTraceFrame should not be used to make security decisions. Still require 
@CallerSensitive for Reflection#getCallerClass(). I like this idea.

***

Regarding ability to obtain j.l.Class instances for classes that client code 
would otherwise have no access to:

What about a simple restriction on methods returning such instances that Class 
objects are only returned when they are resolvable from the ClassLoader of 
client code. If they are not resolvable, null is returned. For example, the 
equivalent of:

public class StackTraceFrame {

     private final Class<?> declaringClass;

     @CallerSensitive
     public Class<?> getDeclaringClass() {
         try {
             return Class.forName(declaringClass.getName(),
                                  false,
                                  Reflection.getCallerClass().getClassLoader())
                    == declaringClass ? declaringClass : null;
             }
         } catch (ClassNotFoundException ignore) {}
         return null;
     }

     // the name can be exposed without fear...
     public String getDeclaringClassName() {
         return declaringClass.getName();
     }


This example could be implemented more efficiently then above code (using 
private Class/ClassLoader API).
Absolutely not. This would be orders of magnitude slower than what I've 
implemented,

Not necessarily. If using internal Class/ClassLoader API (accessible only to java.lang classes, but StackTraceFrame is java.lang class), this might be implemented without security manager checks.

not to mention that it wouldn't even stop any security problem, if one exists. 
On can simply use reflection to get the declaringClass field value regardless 
of what getDeclaringClass returns.

One can simply use reflection to do practically anything if no security manager is installed. If it is, and security policy does not allow it, then you can not access private fields with reflection.

Regards, Peter


N

Regards, Peter


Reply via email to