diff options
author | Deepak Bhole <[email protected]> | 2011-07-15 15:44:56 -0400 |
---|---|---|
committer | Deepak Bhole <[email protected]> | 2011-07-15 15:44:56 -0400 |
commit | dadfb2447d1764e39d7aafb8035e6dba00be7627 (patch) | |
tree | e0893fc21760c45a2f051144c994e18c3dae8be2 /netx/net | |
parent | c5d960db80e654d2203401414fd96b709f704648 (diff) |
RH718164, CVE-2011-2513: Home directory path disclosure to untrusted applications
Diffstat (limited to 'netx/net')
4 files changed, 230 insertions, 11 deletions
diff --git a/netx/net/sourceforge/jnlp/runtime/CachedJarFileCallback.java b/netx/net/sourceforge/jnlp/runtime/CachedJarFileCallback.java new file mode 100644 index 0000000..ca3f4be --- /dev/null +++ b/netx/net/sourceforge/jnlp/runtime/CachedJarFileCallback.java @@ -0,0 +1,157 @@ +/* CachedJarFileCallback.java + Copyright (C) 2011 Red Hat, Inc. + Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. +*/ + +package net.sourceforge.jnlp.runtime; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.jar.JarFile; + +import net.sourceforge.jnlp.util.UrlUtils; + +import sun.net.www.protocol.jar.URLJarFile; +import sun.net.www.protocol.jar.URLJarFileCallBack; + +/** + * Invoked by URLJarFile to get a JarFile corresponding to a URL. + * + * Large parts of this class are based on JarFileFactory and URLJarFile. + */ +final class CachedJarFileCallback implements URLJarFileCallBack { + + private static final CachedJarFileCallback INSTANCE = new CachedJarFileCallback(); + + public synchronized static CachedJarFileCallback getInstance() { + return INSTANCE; + } + + /* our managed cache */ + private final Map<URL, URL> mapping; + + private CachedJarFileCallback() { + mapping = new ConcurrentHashMap<URL, URL>(); + } + + protected void addMapping(URL remoteUrl, URL localUrl) { + mapping.put(remoteUrl, localUrl); + } + + @Override + public JarFile retrieve(URL url) throws IOException { + URL localUrl = mapping.get(url); + + if (localUrl == null) { + /* + * If the jar url is not known, treat it as it would be treated in + * general by URLJarFile. + */ + return cacheJarFile(url); + } + + if (UrlUtils.isLocalFile(localUrl)) { + // if it is known to us, just return the cached file + return new JarFile(localUrl.getPath()); + } else { + // throw new IllegalStateException("a non-local file in cache"); + return null; + } + + } + + /* + * This method is a copy of URLJarFile.retrieve() without the callback check. + */ + private JarFile cacheJarFile(URL url) throws IOException { + JarFile result = null; + + final int BUF_SIZE = 2048; + + /* get the stream before asserting privileges */ + final InputStream in = url.openConnection().getInputStream(); + + try { + result = + AccessController.doPrivileged(new PrivilegedExceptionAction<JarFile>() { + @Override + public JarFile run() throws IOException { + OutputStream out = null; + File tmpFile = null; + try { + tmpFile = File.createTempFile("jar_cache", null); + tmpFile.deleteOnExit(); + out = new FileOutputStream(tmpFile); + int read = 0; + byte[] buf = new byte[BUF_SIZE]; + while ((read = in.read(buf)) != -1) { + out.write(buf, 0, read); + } + out.close(); + out = null; + return new URLJarFile(tmpFile, null); + } catch (IOException e) { + if (tmpFile != null) { + tmpFile.delete(); + } + throw e; + } finally { + if (in != null) { + in.close(); + } + if (out != null) { + out.close(); + } + } + } + }); + } catch (PrivilegedActionException pae) { + throw (IOException) pae.getException(); + } + + return result; + } + +} diff --git a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java index 27e1538..5bad885 100644 --- a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java +++ b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java @@ -147,7 +147,7 @@ public class JNLPClassLoader extends URLClassLoader { /** File entries in the jar files available to this classloader */ private TreeSet<String> jarEntries = new TreeSet<String>(); - /** Map of specific codesources to securitydesc */ + /** Map of specific original (remote) CodeSource Urls to securitydesc */ private HashMap<URL, SecurityDesc> jarLocationSecurityMap = new HashMap<URL, SecurityDesc>(); @@ -509,7 +509,7 @@ public class JNLPClassLoader extends URLClassLoader { } } - jarLocationSecurityMap.put(location, jarSecurity); + jarLocationSecurityMap.put(jarDesc.getLocation(), jarSecurity); } catch (MalformedURLException mfe) { System.err.println(mfe.getMessage()); } @@ -731,7 +731,10 @@ public class JNLPClassLoader extends URLClassLoader { try { URL fileURL = new URL("file://" + extractedJarLocation); - addURL(fileURL); + // there is no remote URL for this, so lets fake one + URL fakeRemote = new URL(jar.getLocation().toString() + "!" + je.getName()); + CachedJarFileCallback.getInstance().addMapping(fakeRemote, fileURL); + addURL(fakeRemote); SecurityDesc jarSecurity = file.getSecurity(); @@ -752,7 +755,7 @@ public class JNLPClassLoader extends URLClassLoader { codebase.getHost()); } - jarLocationSecurityMap.put(fileURL, jarSecurity); + jarLocationSecurityMap.put(fakeRemote, jarSecurity); } catch (MalformedURLException mfue) { if (JNLPRuntime.isDebug()) @@ -767,17 +770,21 @@ public class JNLPClassLoader extends URLClassLoader { } - addURL(location); + addURL(jar.getLocation()); // there is currently no mechanism to cache files per // instance.. so only index cached files if (localFile != null) { + CachedJarFileCallback.getInstance().addMapping(jar.getLocation(), localFile.toURL()); + JarFile jarFile = new JarFile(localFile.getAbsolutePath()); Manifest mf = jarFile.getManifest(); classpaths.addAll(getClassPathsFromManifest(mf, jar.getLocation().getPath())); JarIndex index = JarIndex.getJarIndex(jarFile, null); if (index != null) jarIndexes.add(index); + } else { + CachedJarFileCallback.getInstance().addMapping(jar.getLocation(), jar.getLocation()); } if (JNLPRuntime.isDebug()) @@ -1098,11 +1105,9 @@ public class JNLPClassLoader extends URLClassLoader { ); URL remoteURL = desc.getLocation(); - - URL u = tracker.getCacheURL(remoteURL); - if (u != null) { - addURL(u); - } + URL cachedUrl = tracker.getCacheURL(remoteURL); + addURL(remoteURL); + CachedJarFileCallback.getInstance().addMapping(remoteURL, cachedUrl); } /** @@ -1295,7 +1300,7 @@ public class JNLPClassLoader extends URLClassLoader { /** * Returns the security descriptor for given code source URL * - * @param source The code source + * @param source the origin (remote) url of the code * @return The SecurityDescriptor for that source */ diff --git a/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java b/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java index 69dcf48..9db9466 100644 --- a/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java +++ b/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java @@ -35,6 +35,8 @@ import javax.net.ssl.TrustManager; import javax.swing.UIManager; import javax.swing.text.html.parser.ParserDelegator; +import sun.net.www.protocol.jar.URLJarFile; + import net.sourceforge.jnlp.*; import net.sourceforge.jnlp.browser.BrowserAwareProxySelector; import net.sourceforge.jnlp.cache.*; @@ -237,6 +239,8 @@ public class JNLPRuntime { Security.setProperty("package.access", Security.getProperty("package.access")+",net.sourceforge.jnlp"); + URLJarFile.setCallBack(CachedJarFileCallback.getInstance()); + initialized = true; } diff --git a/netx/net/sourceforge/jnlp/util/UrlUtils.java b/netx/net/sourceforge/jnlp/util/UrlUtils.java new file mode 100644 index 0000000..403b977 --- /dev/null +++ b/netx/net/sourceforge/jnlp/util/UrlUtils.java @@ -0,0 +1,53 @@ +/* UrlUtils.java + Copyright (C) 2011 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 2. + +IcedTea is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. +*/ + +package net.sourceforge.jnlp.util; + +import java.net.URL; + +public class UrlUtils { + + public static boolean isLocalFile(URL url) { + + if (url.getProtocol().equals("file") && + (url.getAuthority() == null || url.getAuthority().equals("")) && + (url.getHost() == null || url.getHost().equals(("")))) { + return true; + } + return false; + } +} |