diff options
author | Sven Gothel <[email protected]> | 2013-06-11 16:25:48 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-06-11 16:25:48 +0200 |
commit | 1a01dce6c42b398cdd68d405828774a3ab366456 (patch) | |
tree | dcbc917b0dbd80c7c5be0b4a9ad35c5489ee64dc /src/java/com/jogamp/common/util/IOUtil.java | |
parent | 377d9de1ff1e2fabcd9bb7f65c0318f3c890392c (diff) |
Bug 752: Review Code Vulnerabilities (Permission Checks of new exposed code and privileged access)
This review focuses on how we perform permission checks,
or better - do we circumvent some assuming full privileges ?
Some native methods do need extra permission validation, i.e. loading native libraries.
Further more AccessController.doPrivileged(..) shall not cover generic code
exposing a critical feature to the user.
Further more .. we should rely on the SecuritManager, i.e. AccessControlContext's
'checkPermission(Permission)' code to comply w/ fine grained permission access.
It is also possible to have full permission w/o having any certificates (-> policy file).
+++
We remove implicit AccessController.doPrivileged(..) from within our trusted code
for generic methods, like Property access, temp. files.
+++
SecurityUtil:
- Remove 'getCommonAccessControlContext(Class<?> clz)',
which returned a local AccessControlContext for later restriction
if the passed class contains all certificates as the 'trusted' GlueGen class has.
- Simply expose convenient permission check methods relying on
SecurityManager / AccessControlContext.
PropertyAccess:
- 'protected static void addTrustedPrefix(..)' requires AllPermissions if SecurityManager is installed.
- Remove implicit doPrivileged(..) triggered by passed AccessControlContext instance,
only leave it for trusted prefixes.
IOUtil:
- Remove all doPrivileged(..) - Elevation shall be performed by caller.
DynamicLinker:
- 'public long openLibraryLocal(..)' and 'public long openLibraryGlobal(..)'
may throw SecurityException, if a SecurityManager is installed and the dyn. link permission
is not granted in the calling code.
Implemented in their respective Unix, OSX and Windows manifestation.
Caller has to elevate privileges via 'doPrivileged(..) {}' !
+++
Tests:
- Property access
- File access
- Native library loading
Manual Applet test (unsigned, but w/ SecurityManager and policy file):
> gluegen/test/applet
Applet has been tested w/ signed JAR w/ Firefox and Java7 on GNU/Linux as well.
Manual Application test (unsigned, but w/ SecurityManager and policy file):
com.jogamp.junit.sec.TestSecIOUtil01
- Run w/ SecurityManager and policy file:
- gluegen/scripts/runtest-secmgr.sh
- Run w/o SecurityManager:
- gluegen/scripts/runtest.sh
Diffstat (limited to 'src/java/com/jogamp/common/util/IOUtil.java')
-rw-r--r-- | src/java/com/jogamp/common/util/IOUtil.java | 100 |
1 files changed, 39 insertions, 61 deletions
diff --git a/src/java/com/jogamp/common/util/IOUtil.java b/src/java/com/jogamp/common/util/IOUtil.java index 46d6b24..2f0c77f 100644 --- a/src/java/com/jogamp/common/util/IOUtil.java +++ b/src/java/com/jogamp/common/util/IOUtil.java @@ -33,12 +33,10 @@ import java.io.BufferedOutputStream; import java.io.Closeable; import java.io.File; import java.io.FileOutputStream; +import java.io.FilePermission; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.lang.reflect.Constructor; import java.net.URI; import java.net.URISyntaxException; @@ -817,20 +815,12 @@ public class IOUtil { * @param dir the directory to process * @param create true if the directory shall be created if not existing * @param executable true if the user intents to launch executables from the temporary directory, otherwise false. - * @param acc The security {@link AccessControlContext} to create directories and test <i>executability</i> * @throws SecurityException if file creation and process execution is not allowed within the current security context */ - public static File testDir(final File dir, final boolean create, final boolean executable, AccessControlContext acc) + public static File testDir(final File dir, final boolean create, final boolean executable) throws SecurityException { - if( null != acc ) { - return AccessController.doPrivileged(new PrivilegedAction<File>() { - public File run() { - return testDirImpl(dir, create, executable); - } }, acc); - } else { - return testDirImpl(dir, create, executable); - } + return testDirImpl(dir, create, executable); } private static boolean isStringSet(String s) { return null != s && 0 < s.length(); } @@ -873,9 +863,35 @@ public class IOUtil { return tmpBaseDir; } - private static File getTempDirImpl(boolean executable) + /** + * Returns a platform independent writable directory for temporary files + * consisting of the platform's {@code temp-root} + {@link #tmpSubDir}, + * e.g. {@code /tmp/jogamp_0000/}. + * <p> + * On standard Java the {@code temp-root} folder is specified by <code>java.io.tempdir</code>. + * </p> + * <p> + * On Android the {@code temp-root} folder is relative to the applications local folder + * (see {@link Context#getDir(String, int)}) is returned, if + * the Android application/activity has registered it's Application Context + * via {@link jogamp.common.os.android.StaticContext.StaticContext#init(Context, ClassLoader) StaticContext.init(..)}. + * This allows using the temp folder w/o the need for <code>sdcard</code> + * access, which would be the <code>java.io.tempdir</code> location on Android! + * </p> + * <p> + * In case {@code temp-root} is the users home folder, + * a dot is being prepended to {@link #tmpSubDir}, i.e.: {@code /home/user/.jogamp_0000/}. + * </p> + * @param executable true if the user intents to launch executables from the temporary directory, otherwise false. + * @throws RuntimeException if no temporary directory could be determined + * @throws SecurityException if access to <code>java.io.tmpdir</code> is not allowed within the current security context + * + * @see PropertyAccess#getProperty(String, boolean) + * @see Context#getDir(String, int) + */ + public static File getTempDir(final boolean executable) throws SecurityException, RuntimeException - { + { if(!tempRootSet) { // volatile: ok synchronized(IOUtil.class) { if(!tempRootSet) { @@ -889,8 +905,8 @@ public class IOUtil { } } - final String java_io_tmpdir = PropertyAccess.getProperty(java_io_tmpdir_propkey, false, null); - final String user_home = PropertyAccess.getProperty(user_home_propkey, false, null); + final String java_io_tmpdir = PropertyAccess.getProperty(java_io_tmpdir_propkey, false); + final String user_home = PropertyAccess.getProperty(user_home_propkey, false); final String xdg_cache_home; { @@ -951,6 +967,8 @@ public class IOUtil { if(null == r) { throw new RuntimeException("Could not determine a temporary directory"); } + final FilePermission fp = new FilePermission(r.getAbsolutePath(), "read,write,delete"); + SecurityUtil.checkPermission(fp); return r; } private static File tempRootExec = null; // writeable and executable @@ -958,53 +976,13 @@ public class IOUtil { private static volatile boolean tempRootSet = false; /** - * Returns a platform independent writable directory for temporary files - * consisting of the platform's {@code temp-root} + {@link #tmpSubDir}, - * e.g. {@code /tmp/jogamp_0000/}. - * <p> - * On standard Java the {@code temp-root} folder is specified by <code>java.io.tempdir</code>. - * </p> - * <p> - * On Android the {@code temp-root} folder is relative to the applications local folder - * (see {@link Context#getDir(String, int)}) is returned, if - * the Android application/activity has registered it's Application Context - * via {@link jogamp.common.os.android.StaticContext.StaticContext#init(Context, ClassLoader) StaticContext.init(..)}. - * This allows using the temp folder w/o the need for <code>sdcard</code> - * access, which would be the <code>java.io.tempdir</code> location on Android! - * </p> - * <p> - * In case {@code temp-root} is the users home folder, - * a dot is being prepended to {@link #tmpSubDir}, i.e.: {@code /home/user/.jogamp_0000/}. - * </p> - * @param executable true if the user intents to launch executables from the temporary directory, otherwise false. - * @param acc The security {@link AccessControlContext} to access properties, environment vars, create directories and test <i>executability</i> - * @throws SecurityException if access to <code>java.io.tmpdir</code> is not allowed within the current security context - * @throws RuntimeException if no temporary directory could be determined - * - * @see PropertyAccess#getProperty(String, boolean, java.security.AccessControlContext) - * @see Context#getDir(String, int) - */ - public static File getTempDir(final boolean executable, AccessControlContext acc) - throws SecurityException, RuntimeException - { - if( null != acc ) { - return AccessController.doPrivileged(new PrivilegedAction<File>() { - public File run() { - return getTempDirImpl(executable); - } }, acc); - } else { - return getTempDirImpl(executable); - } - } - - /** * Utilizing {@link File#createTempFile(String, String, File)} using - * {@link #getTempRoot(AccessControlContext, boolean)} as the directory parameter, ie. location + * {@link #getTempDir(boolean)} as the directory parameter, ie. location * of the root temp folder. * * @see File#createTempFile(String, String) * @see File#createTempFile(String, String, File) - * @see #getTempRoot(AccessControlContext, boolean) + * @see #getTempDir(boolean) * * @param prefix * @param suffix @@ -1014,10 +992,10 @@ public class IOUtil { * @throws IOException * @throws SecurityException */ - public static File createTempFile(String prefix, String suffix, boolean executable, AccessControlContext acc) + public static File createTempFile(String prefix, String suffix, boolean executable) throws IllegalArgumentException, IOException, SecurityException { - return File.createTempFile( prefix, suffix, getTempDir(executable, acc) ); + return File.createTempFile( prefix, suffix, getTempDir(executable) ); } public static void close(Closeable stream, boolean throwRuntimeException) throws RuntimeException { |