@CallerSensitive注解(随笔)

2021-04-15  本文已影响0人  简楼

前言

在阅读Unsafe源码是,以下是Unsafe部分源码:

    @CallerSensitive
    public static Unsafe getUnsafe() {
        Class var0 = Reflection.getCallerClass();
        if (!VM.isSystemDomainLoader(var0.getClassLoader())) {
            throw new SecurityException("Unsafe");
        } else {
            return theUnsafe;
        }
    }

我们可以看到,这个方法上有一个@CallerSensitive注解,所以今天我们就来了解下这个注解。

分析

查看源码,我们可以看到方法内部都调用了Reflection.getCallerClass(),这是一个native方法;
巧的是,这个方法也有@CallerSensitive注解,下面是这个方法的源码:

    @CallerSensitive
    public static native Class<?> getCallerClass();
解释

Caller:调用者,Sensitive:敏感的/易感知的,顾名思义,这是主要针对于方法调用者所做的一些控制;

然而实际上,@CallSensitive是JVM中专用的注解,在类加载过过程中是可以常常看到这个注解;

那么,需要什么权限才能调用这个方法?

  1. 由bootstrap class loader加载的类可以调用
  2. 由extension class loader加载的类可以调用

用户路径的类加载都是由 application class loader进行加载的,也就是用户自定义的类基本上是无法调用此方法的

作用

Reflection.getCallerClass()方法调用所在的方法必须用@CallerSensitive进行注解;
通过此方法获取class时会跳过链路上所有的有@CallerSensitive注解的方法的类;
直到遇到第一个未使用该注解的类,避免了用Reflection.getCallerClass(int n) 这个过时方法来自己做判断;

番外

据说注解是为了堵住漏洞用的,曾经有黑客通过构造双重反射来提升权限,原理是当时反射只检查固定深度的调用者的类,看它有没有特权;

当你尝试用反射调用Reflection.getCallerClass(),结果会抛出异常;

所以在我们日常开发中,可以说作用不大,了解就好了;
主要还是JDK底层控制权限的地方使用。

上一篇 下一篇

猜你喜欢

热点阅读