@CallerSensitive as public API ?

Peter Levart peter.levart at gmail.com
Sun Jul 21 18:57:56 UTC 2013


On 07/20/2013 03:41 AM, Mandy Chung wrote:
> Peter,
>
> FYI.  I have filed this RFE:
>    8020968: Load resource files using the caller's class and class loader
>    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8020968
>
> Mandy

Hi Mandy,

I wonder what API you had in mind. Currently we have ClassLoader and 
Class instance methods to load resources which are quite low-level in 
the sense that they require full or relative path to the resource and 
they return either URL or InputStream. So they usually get wrapped by 
utilities implementing special search strategies and/or resource 
un-marshaling.

For example, imagine one would like to locate resource using the caller 
class' ClassLoader using the resource path composed of the package name 
of the caller class replacing dots with slashes and specified resource 
name appended, then load the content of the resource into a 
BufferedImage and construct an Icon from it, wrapping any IOException 
thrown with some unchecked exception:

package my.pkg;
class MyClass {
void someMethod() {

     // a static utility method:
     Icon saveIcon = Resources.getIcon("save-icon.png");

     // that does the following:
     Icon saveIcon;
     try {
         saveIcon = new 
ImageIcon(ImageIO.read(MyClass.class.getResource("save-icon.png")));
     } catch (IOException e) {
         throw new RuntimeException(e);
     }


I don't suggest creating such APIs in the JDK, just enabling them. So 
what would it take for an API in ClassLoader or Class to enable creating 
an API like Resources.getIcon() presented above?

I guess a static method like Class.getCallerClass() would do, but I have 
a feeling this is something that is flagged as sensitive by the security 
team, right?

So what about Class.getCallerClassResource(String name)? This would not 
locate the resource on behalf of the directly calling class, but the 
class that is calling some method that is calling this method.

Regards, Peter

P.S. I still don't know why would method like Class.getCallerClass() be 
so security sensitive? In order for the getCallerClass() to succeed the 
method calling it would have to be annotated with @CallerSensitive 
annotation. If a method has such annotation, anyone deciding to call 
such method is warned in advance that this method is "extracting" the 
callers class and using it as it finds fit. There's no danger of 
untrusted code to sneak it's own @CallerSensitive methods so that 
unaware code calls them or is it? Does @CallerSensitive work on 
statically resolved methods or on runtime resolved methods? I mean, if 
there is some code in some security-sensitive class:

Runnable r = ....
r.run();

// where a Runnable instance is provided by untrusted code:

class EvilRunnable implements Runnable {
     @Override
     @CallerSensitive
     public void run() {
         Class<?> caller = Class.getCallerClass();
         // do some things with caller....
     }
}


Would @CallerSensitive have desired effect as it is implemented 
currently or would it work only if Runnable.run() interface method was 
annotated?


>
> On 6/25/2013 6:50 PM, Peter Levart wrote:
>> Hi,
>>
>> I know that @CallerSensitive annotation was introduced to bring some 
>> order to JDK internal plumbings. It's scope was to support JDK 
>> internal usage, so it's use is limited to classes loaded by bootstrap 
>> or extension class-loaders. In JDK-internal code it is used mainly 
>> for implementing security-sensitive decisions. But since the 
>> sun.reflect.Reflection.getCallerClass(int) was public and 
>> unrestricted, it found it's way out into user code, where at least I 
>> know that it is used in two areas:
>>
>> 1 - to locate callers in the whole call-stack so that their location 
>> in class-path can be reported (Log4J is an example)
>> 2 - to locate immediate caller so that some resources associated with 
>> it can be located and used (for example localization data in GUI 
>> applications)
>>
>> I don't know how wide-spread 1st usecase is, but the 2nd is common, 
>> since it's use enables APIs that need not explicitly pass-in the 
>> calling class in order to locate resources associated with it (and/or 
>> the class-loader of it). So it would be nice to have such supported 
>> API in JDK8 at least.
>>
>> I'm asking here, to hear any arguments against making such API 
>> supported and public. Are there any security or other issues? If 
>> there aren't, what steps should be taken to introduce such API in the 
>> JDK8 timeframe? I'm thinking of a no-arg method, say 
>> j.l.Class.getCaller() and moving @CallerSensitive to a supported 
>> package + enabling it to mark methods in any class (not just system 
>> and ext classes)...
>>
>> Regards, Peter
>>
>




More information about the core-libs-dev mailing list