Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=62080
Ensure that all reads of the current thread's context class loader made by the UEL API and implementation are performed via a PrivilegedAction to ensure that a SecurityException is not triggered when running under a SecurityManager

git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc8.0.x/trunk@1833003 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/java/javax/el/ELProcessor.java b/java/javax/el/ELProcessor.java
index 2ce1f2d..67b26c7 100644
--- a/java/javax/el/ELProcessor.java
+++ b/java/javax/el/ELProcessor.java
@@ -94,8 +94,7 @@
         Class<?> clazz = context.getImportHandler().resolveClass(className);
 
         if (clazz == null) {
-            clazz = Class.forName(className, true,
-                    Thread.currentThread().getContextClassLoader());
+            clazz = Class.forName(className, true, Util.getContextClassLoader());
         }
 
         if (!Modifier.isPublic(clazz.getModifiers())) {
diff --git a/java/javax/el/ExpressionFactory.java b/java/javax/el/ExpressionFactory.java
index 64d07bc..84bad28 100644
--- a/java/javax/el/ExpressionFactory.java
+++ b/java/javax/el/ExpressionFactory.java
@@ -103,7 +103,7 @@
     public static ExpressionFactory newInstance(Properties properties) {
         ExpressionFactory result = null;
 
-        ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+        ClassLoader tccl = Util.getContextClassLoader();
 
         CacheValue cacheValue;
         Class<?> clazz;
diff --git a/java/javax/el/ImportHandler.java b/java/javax/el/ImportHandler.java
index 479cfe6..60a33f3 100644
--- a/java/javax/el/ImportHandler.java
+++ b/java/javax/el/ImportHandler.java
@@ -190,7 +190,7 @@
 
     private Class<?> findClass(String name, boolean throwException) {
         Class<?> clazz;
-        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        ClassLoader cl = Util.getContextClassLoader();
         String path = name.replace('.', '/') + ".class";
         try {
             /* Given that findClass() has to be called for every imported
diff --git a/java/javax/el/Util.java b/java/javax/el/Util.java
index e401b98..1dfd0a8 100644
--- a/java/javax/el/Util.java
+++ b/java/javax/el/Util.java
@@ -21,6 +21,8 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -92,7 +94,8 @@
      */
     static ExpressionFactory getExpressionFactory() {
 
-        ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+        ClassLoader tccl = getContextClassLoader();
+
         CacheValue cacheValue = null;
         ExpressionFactory factory = null;
 
@@ -658,6 +661,19 @@
     }
 
 
+    static ClassLoader getContextClassLoader() {
+        ClassLoader tccl;
+        if (System.getSecurityManager() != null) {
+            PrivilegedAction<ClassLoader> pa = new PrivilegedGetTccl();
+            tccl = AccessController.doPrivileged(pa);
+        } else {
+            tccl = Thread.currentThread().getContextClassLoader();
+        }
+
+        return tccl;
+    }
+
+
     private abstract static class Wrapper {
 
         public static List<Wrapper> wrap(Method[] methods, String name) {
@@ -794,4 +810,12 @@
             return cmp;
         }
     }
+
+
+    private static class PrivilegedGetTccl implements PrivilegedAction<ClassLoader> {
+        @Override
+        public ClassLoader run() {
+            return Thread.currentThread().getContextClassLoader();
+        }
+    }
 }
diff --git a/java/org/apache/el/util/ReflectionUtil.java b/java/org/apache/el/util/ReflectionUtil.java
index 271d60c..e7f8adc 100644
--- a/java/org/apache/el/util/ReflectionUtil.java
+++ b/java/org/apache/el/util/ReflectionUtil.java
@@ -19,6 +19,8 @@
 import java.lang.reflect.Array;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
@@ -57,10 +59,10 @@
         if (c == null) {
             if (name.endsWith("[]")) {
                 String nc = name.substring(0, name.length() - 2);
-                c = Class.forName(nc, true, Thread.currentThread().getContextClassLoader());
+                c = Class.forName(nc, true, getContextClassLoader());
                 c = Array.newInstance(c, 0).getClass();
             } else {
-                c = Class.forName(name, true, Thread.currentThread().getContextClassLoader());
+                c = Class.forName(name, true, getContextClassLoader());
             }
         }
         return c;
@@ -476,6 +478,28 @@
         return null;
     }
 
+
+    private static ClassLoader getContextClassLoader() {
+        ClassLoader tccl;
+        if (System.getSecurityManager() != null) {
+            PrivilegedAction<ClassLoader> pa = new PrivilegedGetTccl();
+            tccl = AccessController.doPrivileged(pa);
+        } else {
+            tccl = Thread.currentThread().getContextClassLoader();
+        }
+
+        return tccl;
+    }
+
+
+    private static class PrivilegedGetTccl implements PrivilegedAction<ClassLoader> {
+        @Override
+        public ClassLoader run() {
+            return Thread.currentThread().getContextClassLoader();
+        }
+    }
+
+
     /*
      * This class duplicates code in javax.el.Util. When making changes keep
      * the code in sync.
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 93c3264..9f91b97 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -161,6 +161,13 @@
   <subsection name="Jasper">
     <changelog>
       <fix>
+        <bug>62080</bug>: Ensure that all reads of the current thread's context
+        class loader made by the UEL API and implementation are performed via a
+        <code>PrivilegedAction</code> to ensure that a
+        <code>SecurityException</code> is not triggered when running under a
+        <code>SecurityManager</code>. (mark)
+      </fix>
+      <fix>
         <bug>62350</bug>: Refactor
         <code>org.apache.jasper.runtime.BodyContentImpl</code> so a
         <code>SecurityException</code> is not thrown when running under a