Skip to content

Commit d5d3104

Browse files
author
Costin Leau
committed
+ interaction with user code uses now dedicated privileged when running under a security manager
1 parent fe5b502 commit d5d3104

21 files changed

+1099
-118
lines changed

org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java

Lines changed: 80 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
import java.lang.reflect.InvocationTargetException;
2323
import java.lang.reflect.Method;
2424
import java.lang.reflect.Modifier;
25+
import java.security.AccessControlContext;
26+
import java.security.AccessController;
27+
import java.security.PrivilegedActionException;
28+
import java.security.PrivilegedExceptionAction;
2529
import java.util.ArrayList;
2630
import java.util.HashMap;
2731
import java.util.Iterator;
@@ -31,7 +35,6 @@
3135

3236
import org.apache.commons.logging.Log;
3337
import org.apache.commons.logging.LogFactory;
34-
3538
import org.springframework.core.GenericCollectionTypeResolver;
3639
import org.springframework.core.MethodParameter;
3740
import org.springframework.util.Assert;
@@ -102,6 +105,9 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
102105
*/
103106
private Map<String, BeanWrapperImpl> nestedBeanWrappers;
104107

108+
/** The security context used for invoking the property methods */
109+
private AccessControlContext acc;
110+
105111

106112
/**
107113
* Create new empty BeanWrapperImpl. Wrapped instance needs to be set afterwards.
@@ -198,6 +204,16 @@ public void setWrappedInstance(Object object, String nestedPath, Object rootObje
198204
setIntrospectionClass(object.getClass());
199205
}
200206

207+
/**
208+
* Set the security context used during the invocation of the wrapped instance methods.
209+
* Can be null.
210+
*
211+
* @param acc
212+
*/
213+
public void setSecurityContext(AccessControlContext acc) {
214+
this.acc = acc;
215+
}
216+
201217
public final Object getWrappedInstance() {
202218
return this.object;
203219
}
@@ -539,12 +555,29 @@ private Object getPropertyValue(PropertyTokenHolder tokens) throws BeansExceptio
539555
if (pd == null || pd.getReadMethod() == null) {
540556
throw new NotReadablePropertyException(getRootClass(), this.nestedPath + propertyName);
541557
}
542-
Method readMethod = pd.getReadMethod();
558+
final Method readMethod = pd.getReadMethod();
543559
try {
544560
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
545561
readMethod.setAccessible(true);
546562
}
547-
Object value = readMethod.invoke(this.object, (Object[]) null);
563+
564+
Object value = null;
565+
566+
if (System.getSecurityManager() != null) {
567+
try {
568+
value = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
569+
public Object run() throws Exception {
570+
return readMethod.invoke(object, (Object[]) null);
571+
}
572+
},acc);
573+
} catch (PrivilegedActionException pae) {
574+
throw pae.getException();
575+
}
576+
}
577+
else {
578+
value = readMethod.invoke(object, (Object[]) null);
579+
}
580+
548581
if (tokens.keys != null) {
549582
// apply indexes and map keys
550583
for (int i = 0; i < tokens.keys.length; i++) {
@@ -602,7 +635,8 @@ else if (value instanceof Map) {
602635
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
603636
"Getter for property '" + actualName + "' threw exception", ex);
604637
}
605-
catch (IllegalAccessException ex) {
638+
639+
catch(IllegalAccessException ex) {
606640
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
607641
"Illegal attempt to get property '" + actualName + "' threw exception", ex);
608642
}
@@ -614,6 +648,10 @@ else if (value instanceof Map) {
614648
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
615649
"Invalid index in property path '" + propertyName + "'", ex);
616650
}
651+
catch (Exception ex) {
652+
throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
653+
"Invalid index in property path '" + propertyName + "'", ex);
654+
}
617655
}
618656

619657
@Override
@@ -813,14 +851,26 @@ else if (propValue instanceof Map) {
813851
}
814852
else {
815853
if (isExtractOldValueForEditor() && pd.getReadMethod() != null) {
816-
Method readMethod = pd.getReadMethod();
854+
final Method readMethod = pd.getReadMethod();
817855
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
818856
readMethod.setAccessible(true);
819857
}
820858
try {
821-
oldValue = readMethod.invoke(this.object);
859+
if (System.getSecurityManager() != null) {
860+
oldValue = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
861+
public Object run() throws Exception {
862+
return readMethod.invoke(object);
863+
}
864+
},acc);
865+
}
866+
else {
867+
oldValue = readMethod.invoke(object);
868+
}
822869
}
823870
catch (Exception ex) {
871+
if (ex instanceof PrivilegedActionException) {
872+
ex = ((PrivilegedActionException) ex).getException();
873+
}
824874
if (logger.isDebugEnabled()) {
825875
logger.debug("Could not read previous value of property '" +
826876
this.nestedPath + propertyName + "'", ex);
@@ -831,11 +881,28 @@ else if (propValue instanceof Map) {
831881
}
832882
pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
833883
}
834-
Method writeMethod = pd.getWriteMethod();
884+
final Method writeMethod = pd.getWriteMethod();
835885
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
836886
writeMethod.setAccessible(true);
837887
}
838-
writeMethod.invoke(this.object, valueToApply);
888+
final Object value = valueToApply;
889+
890+
if (System.getSecurityManager() != null) {
891+
try {
892+
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
893+
public Object run() throws Exception {
894+
writeMethod.invoke(object, value);
895+
return null;
896+
}
897+
},acc);
898+
} catch (PrivilegedActionException ex) {
899+
throw ex.getException();
900+
}
901+
}
902+
else {
903+
writeMethod.invoke(object, value);
904+
}
905+
839906
}
840907
catch (InvocationTargetException ex) {
841908
PropertyChangeEvent propertyChangeEvent =
@@ -862,6 +929,11 @@ else if (propValue instanceof Map) {
862929
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
863930
throw new MethodInvocationException(pce, ex);
864931
}
932+
catch (Exception ex) {
933+
PropertyChangeEvent pce =
934+
new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
935+
throw new MethodInvocationException(pce, ex);
936+
}
865937
}
866938
}
867939

org.springframework.beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java

Lines changed: 100 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import java.security.AccessControlContext;
2525
import java.security.AccessController;
2626
import java.security.PrivilegedAction;
27+
import java.security.PrivilegedActionException;
28+
import java.security.PrivilegedExceptionAction;
2729
import java.util.ArrayList;
2830
import java.util.Arrays;
2931
import java.util.Collection;
@@ -330,13 +332,27 @@ public Object createBean(Class beanClass, int autowireMode, boolean dependencyCh
330332

331333
public Object autowire(Class beanClass, int autowireMode, boolean dependencyCheck) throws BeansException {
332334
// Use non-singleton bean definition, to avoid registering bean as dependent bean.
333-
RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
335+
final RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
334336
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
335337
if (bd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR) {
336338
return autowireConstructor(beanClass.getName(), bd, null, null).getWrappedInstance();
337339
}
338340
else {
339-
Object bean = getInstantiationStrategy().instantiate(bd, null, this);
341+
Object bean = null;
342+
final BeanFactory parent = this;
343+
344+
if (System.getSecurityManager() != null) {
345+
bean = AccessController.doPrivileged(new PrivilegedAction<Object>() {
346+
347+
public Object run() {
348+
return getInstantiationStrategy().instantiate(bd, null, parent);
349+
}
350+
}, getAccessControlContext());
351+
}
352+
else {
353+
bean = getInstantiationStrategy().instantiate(bd, null, parent);
354+
}
355+
340356
populateBean(beanClass.getName(), bd, new BeanWrapperImpl(bean));
341357
return bean;
342358
}
@@ -403,9 +419,6 @@ public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, St
403419
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
404420
throws BeanCreationException {
405421

406-
AccessControlContext acc = AccessController.getContext();
407-
return AccessController.doPrivileged(new PrivilegedAction<Object>() {
408-
public Object run() {
409422
if (logger.isDebugEnabled()) {
410423
logger.debug("Creating instance of bean '" + beanName + "'");
411424
}
@@ -438,8 +451,6 @@ public Object run() {
438451
logger.debug("Finished creating instance of bean '" + beanName + "'");
439452
}
440453
return beanInstance;
441-
}
442-
}, acc);
443454
}
444455

445456
/**
@@ -904,9 +915,22 @@ protected Constructor[] determineConstructorsFromBeanPostProcessors(Class beanCl
904915
* @param mbd the bean definition for the bean
905916
* @return BeanWrapper for the new instance
906917
*/
907-
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
918+
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
908919
try {
909-
Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
920+
Object beanInstance = null;
921+
final BeanFactory parent = this;
922+
if (System.getSecurityManager() != null) {
923+
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
924+
925+
public Object run() {
926+
return getInstantiationStrategy().instantiate(mbd, beanName, parent);
927+
}
928+
}, getAccessControlContext());
929+
}
930+
else {
931+
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
932+
}
933+
910934
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
911935
initBeanWrapper(bw);
912936
return bw;
@@ -1229,6 +1253,12 @@ protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrap
12291253

12301254
MutablePropertyValues mpvs = null;
12311255
List<PropertyValue> original;
1256+
1257+
if (System.getSecurityManager()!= null) {
1258+
if (bw instanceof BeanWrapperImpl) {
1259+
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
1260+
}
1261+
}
12321262

12331263
if (pvs instanceof MutablePropertyValues) {
12341264
mpvs = (MutablePropertyValues) pvs;
@@ -1337,19 +1367,20 @@ private Object convertForProperty(Object value, String propertyName, BeanWrapper
13371367
* @see #invokeInitMethods
13381368
* @see #applyBeanPostProcessorsAfterInitialization
13391369
*/
1340-
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
1341-
if (bean instanceof BeanNameAware) {
1342-
((BeanNameAware) bean).setBeanName(beanName);
1343-
}
1344-
1345-
if (bean instanceof BeanClassLoaderAware) {
1346-
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
1370+
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
1371+
1372+
if (System.getSecurityManager() != null) {
1373+
AccessController.doPrivileged(new PrivilegedAction<Object>() {
1374+
public Object run() {
1375+
invokeAwareMethods(beanName, bean);
1376+
return null;
1377+
}
1378+
}, getAccessControlContext());
13471379
}
1348-
1349-
if (bean instanceof BeanFactoryAware) {
1350-
((BeanFactoryAware) bean).setBeanFactory(this);
1380+
else {
1381+
invokeAwareMethods(beanName, bean);
13511382
}
1352-
1383+
13531384
Object wrappedBean = bean;
13541385
if (mbd == null || !mbd.isSynthetic()) {
13551386
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
@@ -1369,6 +1400,20 @@ protected Object initializeBean(String beanName, Object bean, RootBeanDefinition
13691400
}
13701401
return wrappedBean;
13711402
}
1403+
1404+
private void invokeAwareMethods(final String beanName, final Object bean) {
1405+
if (bean instanceof BeanNameAware) {
1406+
((BeanNameAware) bean).setBeanName(beanName);
1407+
}
1408+
1409+
if (bean instanceof BeanClassLoaderAware) {
1410+
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
1411+
}
1412+
1413+
if (bean instanceof BeanFactoryAware) {
1414+
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
1415+
}
1416+
}
13721417

13731418
/**
13741419
* Give a bean a chance to react now all its properties are set,
@@ -1382,15 +1427,30 @@ protected Object initializeBean(String beanName, Object bean, RootBeanDefinition
13821427
* @throws Throwable if thrown by init methods or by the invocation process
13831428
* @see #invokeCustomInitMethod
13841429
*/
1385-
protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mbd)
1430+
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
13861431
throws Throwable {
13871432

13881433
boolean isInitializingBean = (bean instanceof InitializingBean);
13891434
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
13901435
if (logger.isDebugEnabled()) {
13911436
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
13921437
}
1393-
((InitializingBean) bean).afterPropertiesSet();
1438+
1439+
if (System.getSecurityManager() != null) {
1440+
try {
1441+
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
1442+
public Object run() throws Exception {
1443+
((InitializingBean) bean).afterPropertiesSet();
1444+
return null;
1445+
}
1446+
},getAccessControlContext());
1447+
} catch (PrivilegedActionException pae) {
1448+
throw pae.getException();
1449+
}
1450+
}
1451+
else {
1452+
((InitializingBean) bean).afterPropertiesSet();
1453+
}
13941454
}
13951455

13961456
if (mbd != null) {
@@ -1413,9 +1473,9 @@ protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinitio
14131473
* @param enforceInitMethod indicates whether the defined init method needs to exist
14141474
* @see #invokeInitMethods
14151475
*/
1416-
protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd) throws Throwable {
1476+
protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
14171477
String initMethodName = mbd.getInitMethodName();
1418-
Method initMethod = (mbd.isNonPublicAccessAllowed() ?
1478+
final Method initMethod = (mbd.isNonPublicAccessAllowed() ?
14191479
BeanUtils.findMethod(bean.getClass(), initMethodName) :
14201480
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
14211481
if (initMethod == null) {
@@ -1437,11 +1497,23 @@ protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefi
14371497
logger.debug("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");
14381498
}
14391499
ReflectionUtils.makeAccessible(initMethod);
1440-
try {
1441-
initMethod.invoke(bean, (Object[]) null);
1500+
if (System.getSecurityManager() != null) {
1501+
try {
1502+
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
1503+
1504+
public Object run() throws Exception {
1505+
initMethod.invoke(bean, (Object[]) null);
1506+
return null;
1507+
}
1508+
}, getAccessControlContext());
1509+
}
1510+
catch (PrivilegedActionException pae) {
1511+
InvocationTargetException ex = (InvocationTargetException) pae.getException();
1512+
throw ex.getTargetException();
1513+
}
14421514
}
1443-
catch (InvocationTargetException ex) {
1444-
throw ex.getTargetException();
1515+
else {
1516+
initMethod.invoke(bean, (Object[]) null);
14451517
}
14461518
}
14471519

0 commit comments

Comments
 (0)