Merge branch 'jarhell2.0' into 1702090
This commit is contained in:
commit
c663d9b6a5
|
@ -26,6 +26,7 @@ import org.elasticsearch.common.logging.ESLogger;
|
||||||
import org.elasticsearch.common.logging.Loggers;
|
import org.elasticsearch.common.logging.Loggers;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.nio.file.FileVisitResult;
|
import java.nio.file.FileVisitResult;
|
||||||
|
@ -70,21 +71,43 @@ public class JarHell {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the current classloader for duplicate classes
|
* Checks the current classpath for duplicate classes
|
||||||
* @throws IllegalStateException if jar hell was found
|
* @throws IllegalStateException if jar hell was found
|
||||||
*/
|
*/
|
||||||
public static void checkJarHell() throws Exception {
|
public static void checkJarHell() throws Exception {
|
||||||
ClassLoader loader = JarHell.class.getClassLoader();
|
ClassLoader loader = JarHell.class.getClassLoader();
|
||||||
if (loader instanceof URLClassLoader == false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ESLogger logger = Loggers.getLogger(JarHell.class);
|
ESLogger logger = Loggers.getLogger(JarHell.class);
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("java.class.path: {}", System.getProperty("java.class.path"));
|
logger.debug("java.class.path: {}", System.getProperty("java.class.path"));
|
||||||
logger.debug("sun.boot.class.path: {}", System.getProperty("sun.boot.class.path"));
|
logger.debug("sun.boot.class.path: {}", System.getProperty("sun.boot.class.path"));
|
||||||
|
if (loader instanceof URLClassLoader ) {
|
||||||
logger.debug("classloader urls: {}", Arrays.toString(((URLClassLoader)loader).getURLs()));
|
logger.debug("classloader urls: {}", Arrays.toString(((URLClassLoader)loader).getURLs()));
|
||||||
}
|
}
|
||||||
checkJarHell(((URLClassLoader) loader).getURLs());
|
}
|
||||||
|
checkJarHell(parseClassPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the classpath into a set of URLs
|
||||||
|
*/
|
||||||
|
@SuppressForbidden(reason = "resolves against CWD because that is how classpaths work")
|
||||||
|
public static URL[] parseClassPath() {
|
||||||
|
String elements[] = System.getProperty("java.class.path").split(System.getProperty("path.separator"));
|
||||||
|
URL urlElements[] = new URL[elements.length];
|
||||||
|
for (int i = 0; i < elements.length; i++) {
|
||||||
|
String element = elements[i];
|
||||||
|
// empty classpath element behaves like CWD.
|
||||||
|
if (element.isEmpty()) {
|
||||||
|
element = System.getProperty("user.dir");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
urlElements[i] = PathUtils.get(element).toUri().toURL();
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
// should not happen, as we use the filesystem API
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return urlElements;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -24,7 +24,6 @@ import org.elasticsearch.env.Environment;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
|
||||||
import java.nio.file.AccessMode;
|
import java.nio.file.AccessMode;
|
||||||
import java.nio.file.FileAlreadyExistsException;
|
import java.nio.file.FileAlreadyExistsException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
@ -133,9 +132,7 @@ final class Security {
|
||||||
*/
|
*/
|
||||||
@SuppressForbidden(reason = "proper use of URL")
|
@SuppressForbidden(reason = "proper use of URL")
|
||||||
static void setCodebaseProperties() {
|
static void setCodebaseProperties() {
|
||||||
ClassLoader loader = Security.class.getClassLoader();
|
for (URL url : JarHell.parseClassPath()) {
|
||||||
if (loader instanceof URLClassLoader) {
|
|
||||||
for (URL url : ((URLClassLoader)loader).getURLs()) {
|
|
||||||
for (Map.Entry<Pattern,String> e : SPECIAL_JARS.entrySet()) {
|
for (Map.Entry<Pattern,String> e : SPECIAL_JARS.entrySet()) {
|
||||||
if (e.getKey().matcher(url.getPath()).matches()) {
|
if (e.getKey().matcher(url.getPath()).matches()) {
|
||||||
String prop = e.getValue();
|
String prop = e.getValue();
|
||||||
|
@ -151,10 +148,6 @@ final class Security {
|
||||||
System.setProperty(prop, "file:/dev/null"); // no chance to be interpreted as "all"
|
System.setProperty(prop, "file:/dev/null"); // no chance to be interpreted as "all"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// we could try to parse the classpath or something, but screw it for now.
|
|
||||||
throw new UnsupportedOperationException("Unsupported system classloader type: " + loader.getClass());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** returns dynamic Permissions to configured paths */
|
/** returns dynamic Permissions to configured paths */
|
||||||
|
|
|
@ -41,7 +41,6 @@ import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
import java.nio.file.attribute.PosixFileAttributeView;
|
import java.nio.file.attribute.PosixFileAttributeView;
|
||||||
|
@ -315,10 +314,7 @@ public class PluginManager {
|
||||||
private void jarHellCheck(Path candidate, boolean isolated) throws IOException {
|
private void jarHellCheck(Path candidate, boolean isolated) throws IOException {
|
||||||
// create list of current jars in classpath
|
// create list of current jars in classpath
|
||||||
final List<URL> jars = new ArrayList<>();
|
final List<URL> jars = new ArrayList<>();
|
||||||
ClassLoader loader = PluginManager.class.getClassLoader();
|
jars.addAll(Arrays.asList(JarHell.parseClassPath()));
|
||||||
if (loader instanceof URLClassLoader) {
|
|
||||||
Collections.addAll(jars, ((URLClassLoader) loader).getURLs());
|
|
||||||
}
|
|
||||||
|
|
||||||
// read existing bundles. this does some checks on the installation too.
|
// read existing bundles. this does some checks on the installation too.
|
||||||
List<Bundle> bundles = PluginsService.getPluginBundles(environment.pluginsFile());
|
List<Bundle> bundles = PluginsService.getPluginBundles(environment.pluginsFile());
|
||||||
|
|
|
@ -47,6 +47,7 @@ import java.nio.file.DirectoryStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -331,12 +332,7 @@ public class PluginsService extends AbstractComponent {
|
||||||
// pluginmanager does it, but we do it again, in case lusers mess with jar files manually
|
// pluginmanager does it, but we do it again, in case lusers mess with jar files manually
|
||||||
try {
|
try {
|
||||||
final List<URL> jars = new ArrayList<>();
|
final List<URL> jars = new ArrayList<>();
|
||||||
ClassLoader parentLoader = getClass().getClassLoader();
|
jars.addAll(Arrays.asList(JarHell.parseClassPath()));
|
||||||
if (parentLoader instanceof URLClassLoader) {
|
|
||||||
for (URL url : ((URLClassLoader) parentLoader).getURLs()) {
|
|
||||||
jars.add(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jars.addAll(bundle.urls);
|
jars.addAll(bundle.urls);
|
||||||
JarHell.checkJarHell(jars.toArray(new URL[0]));
|
JarHell.checkJarHell(jars.toArray(new URL[0]));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -86,7 +86,7 @@ public class BootstrapForTesting {
|
||||||
// initialize paths the same exact way as bootstrap.
|
// initialize paths the same exact way as bootstrap.
|
||||||
Permissions perms = new Permissions();
|
Permissions perms = new Permissions();
|
||||||
// add permissions to everything in classpath
|
// add permissions to everything in classpath
|
||||||
for (URL url : ((URLClassLoader)BootstrapForTesting.class.getClassLoader()).getURLs()) {
|
for (URL url : JarHell.parseClassPath()) {
|
||||||
Path path = PathUtils.get(url.toURI());
|
Path path = PathUtils.get(url.toURI());
|
||||||
// resource itself
|
// resource itself
|
||||||
perms.add(new FilePermission(path.toString(), "read,readlink"));
|
perms.add(new FilePermission(path.toString(), "read,readlink"));
|
||||||
|
|
Loading…
Reference in New Issue