+ added fine grained privileged blocks to preserve the caller security stack when invoking the callee

This commit is contained in:
Costin Leau
2009-08-06 22:31:57 +00:00
parent 81eb11486d
commit af8af8c633
8 changed files with 371 additions and 73 deletions

View File

@@ -24,6 +24,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
@@ -557,8 +558,18 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
}
final Method readMethod = pd.getReadMethod();
try {
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
readMethod.setAccessible(true);
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers()) && !readMethod.isAccessible()) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
readMethod.setAccessible(true);
return null;
}
});
}
else {
readMethod.setAccessible(true);
}
}
Object value = null;
@@ -852,8 +863,18 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
else {
if (isExtractOldValueForEditor() && pd.getReadMethod() != null) {
final Method readMethod = pd.getReadMethod();
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
readMethod.setAccessible(true);
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers()) && !readMethod.isAccessible()) {
if (System.getSecurityManager()!= null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
readMethod.setAccessible(true);
return null;
}
});
}
else {
readMethod.setAccessible(true);
}
}
try {
if (System.getSecurityManager() != null) {
@@ -882,8 +903,18 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
}
final Method writeMethod = pd.getWriteMethod();
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
writeMethod.setAccessible(true);
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers()) && !writeMethod.isAccessible()) {
if (System.getSecurityManager()!= null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
writeMethod.setAccessible(true);
return null;
}
});
}
else {
writeMethod.setAccessible(true);
}
}
final Object value = valueToApply;

View File

@@ -1496,8 +1496,15 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
if (logger.isDebugEnabled()) {
logger.debug("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");
}
ReflectionUtils.makeAccessible(initMethod);
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
ReflectionUtils.makeAccessible(initMethod);
return null;
}
});
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@@ -1514,6 +1521,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
}
else {
try {
ReflectionUtils.makeAccessible(initMethod);
initMethod.invoke(bean, (Object[]) null);
}
catch (InvocationTargetException ex) {

View File

@@ -209,16 +209,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
final String name, final Class<T> requiredType, final Object[] args, final boolean typeCheckOnly)
throws BeansException {
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged(new PrivilegedAction<T>() {
public T run() {
return doGetBeanRaw(name, requiredType, args, typeCheckOnly);
}
});
}
else {
return doGetBeanRaw(name, requiredType, args, typeCheckOnly);
}
}
/**
* Return an instance, which may be shared or independent, of the specified bean.
@@ -1446,7 +1437,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
@Override
protected AccessControlContext getAccessControlContext() {
SecurityContextProvider provider = getSecurityContextProvider();
return (provider != null ? provider.getAccessControlContext(): null);
return (provider != null ? provider.getAccessControlContext(): AccessController.getContext());
}
/**

View File

@@ -385,8 +385,23 @@ class ConstructorResolver {
// Need to determine the factory method...
// Try all methods with this name to see if they match the given arguments.
factoryClass = ClassUtils.getUserClass(factoryClass);
Method[] rawCandidates = (mbd.isNonPublicAccessAllowed() ?
ReflectionUtils.getAllDeclaredMethods(factoryClass) : factoryClass.getMethods());
Method[] rawCandidates = null;
final Class factoryClazz = factoryClass;
if (System.getSecurityManager() != null) {
rawCandidates = AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
public Method[] run() {
return (mbd.isNonPublicAccessAllowed() ?
ReflectionUtils.getAllDeclaredMethods(factoryClazz) : factoryClazz.getMethods());
}
});
}
else {
rawCandidates = (mbd.isNonPublicAccessAllowed() ?
ReflectionUtils.getAllDeclaredMethods(factoryClazz) : factoryClazz.getMethods());
}
List<Method> candidateSet = new ArrayList<Method>();
for (Method candidate : rawCandidates) {
if (Modifier.isStatic(candidate.getModifiers()) == isStatic &&

View File

@@ -21,6 +21,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
@@ -81,7 +82,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
* @param postProcessors the List of BeanPostProcessors
* (potentially DestructionAwareBeanPostProcessor), if any
*/
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
public DisposableBeanAdapter(final Object bean, String beanName, RootBeanDefinition beanDefinition,
List<BeanPostProcessor> postProcessors, AccessControlContext acc) {
Assert.notNull(bean, "Bean must not be null");
@@ -92,14 +93,26 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
this.acc = acc;
String destroyMethodName = beanDefinition.getDestroyMethodName();
final String destroyMethodName = beanDefinition.getDestroyMethodName();
if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
this.destroyMethodName = destroyMethodName;
try {
this.destroyMethod = (this.nonPublicAccessAllowed ?
BeanUtils.findMethodWithMinimalParameters(bean.getClass(), destroyMethodName) :
BeanUtils.findMethodWithMinimalParameters(bean.getClass().getMethods(), destroyMethodName));
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
destroyMethod = (nonPublicAccessAllowed ?
BeanUtils.findMethodWithMinimalParameters(bean.getClass(), destroyMethodName) :
BeanUtils.findMethodWithMinimalParameters(bean.getClass().getMethods(), destroyMethodName));
return null;
}
});
}
else {
this.destroyMethod = (this.nonPublicAccessAllowed ?
BeanUtils.findMethodWithMinimalParameters(bean.getClass(), destroyMethodName) :
BeanUtils.findMethodWithMinimalParameters(bean.getClass().getMethods(), destroyMethodName));
}
}
catch (IllegalArgumentException ex) {
throw new BeanDefinitionValidationException("Couldn't find a unique destroy method on bean with name '" +
@@ -229,9 +242,15 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
logger.debug("Invoking destroy method '" + this.destroyMethodName +
"' on bean with name '" + this.beanName + "'");
}
ReflectionUtils.makeAccessible(destroyMethod);
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
ReflectionUtils.makeAccessible(destroyMethod);
return null;
}
});
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
@@ -244,6 +263,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
}
}
else {
ReflectionUtils.makeAccessible(destroyMethod);
destroyMethod.invoke(bean, args);
}
} catch (InvocationTargetException ex) {

View File

@@ -89,9 +89,18 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
public Object instantiate(
RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
Constructor ctor, Object[] args) {
final Constructor ctor, Object[] args) {
if (beanDefinition.getMethodOverrides().isEmpty()) {
if (System.getSecurityManager() != null) {
// use own privileged to change accessibility (when security is on)
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
ReflectionUtils.makeAccessible(ctor);
return null;
}
});
}
return BeanUtils.instantiateClass(ctor, args);
}
else {