diff options
author | Sven Gothel <[email protected]> | 2015-02-05 00:25:48 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2015-02-05 00:25:48 +0100 |
commit | 06a05d30fc026b21f59310986ea9eb7f3ff30d54 (patch) | |
tree | f491985eb2b9adde2627ceb09aa64f3614e72ab5 /src/jogl/classes/jogamp | |
parent | 3317e7a427fbb81dd3d7daa8116c7d33166ed003 (diff) |
Add missing privileged section for NativeLibrary lookup: GLContextImpl and FFMPEGDynamicLibraryBundleInfo
Since GlueGen security fix commit 12feaa7d3b1544098f684d851e3caff1ec88cbc8
and its cleanup dd2440cbadc642a561d8f92c502fe822b2f11762
the GLContextImpl func lookup caused a security exception.
Applied fix to FFMPEGDynamicLibraryBundleInfo as well.
Diffstat (limited to 'src/jogl/classes/jogamp')
-rw-r--r-- | src/jogl/classes/jogamp/opengl/GLContextImpl.java | 123 | ||||
-rw-r--r-- | src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java | 69 |
2 files changed, 100 insertions, 92 deletions
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java index 26a5566c2..1ff64725a 100644 --- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java @@ -100,6 +100,9 @@ public abstract class GLContextImpl extends GLContext { private String glRenderer; private String glRendererLowerCase; private String glVersion; + private boolean glGetPtrInit = false; + private long glGetStringPtr = 0; + private long glGetIntegervPtr = 0; // Tracks lifecycle of buffer objects to avoid // repeated glGet calls upon glMapBuffer operations @@ -196,6 +199,9 @@ public abstract class GLContextImpl extends GLContext { glRenderer = glVendor; glRendererLowerCase = glRenderer; glVersion = glVendor; + glGetPtrInit = false; + glGetStringPtr = 0; + glGetIntegervPtr = 0; if ( !isInit && null != boundFBOTarget ) { // <init>: boundFBOTarget is not written yet boundFBOTarget[0] = 0; // draw @@ -1367,17 +1373,32 @@ public abstract class GLContextImpl extends GLContext { } ); } + private final PrivilegedAction<Object> privInitGLGetPtrAction = new PrivilegedAction<Object>() { + @Override + public Object run() { + final GLDynamicLookupHelper glDynLookupHelper = getDrawableImpl().getGLDynamicLookupHelper(); + glDynLookupHelper.claimAllLinkPermission(); + try { + glGetStringPtr = glDynLookupHelper.dynamicLookupFunction("glGetString"); + glGetIntegervPtr = glDynLookupHelper.dynamicLookupFunction("glGetIntegerv"); + } finally { + glDynLookupHelper.releaseAllLinkPermission(); + } + return null; + } }; private final boolean initGLRendererAndGLVersionStrings() { - final GLDynamicLookupHelper glDynLookupHelper = getDrawableImpl().getGLDynamicLookupHelper(); - final long _glGetString = glDynLookupHelper.dynamicLookupFunction("glGetString"); - if(0 == _glGetString) { - System.err.println("Error: Entry point to 'glGetString' is NULL."); + if( !glGetPtrInit ) { + AccessController.doPrivileged(privInitGLGetPtrAction); + glGetPtrInit = true; + } + if( 0 == glGetStringPtr || 0 == glGetIntegervPtr ) { + System.err.println("Error: Could not lookup: glGetString "+toHexString(glGetStringPtr)+", glGetIntegerv "+toHexString(glGetIntegervPtr)); if(DEBUG) { ExceptionUtils.dumpStack(System.err); } return false; } else { - final String _glVendor = glGetStringInt(GL.GL_VENDOR, _glGetString); + final String _glVendor = glGetStringInt(GL.GL_VENDOR, glGetStringPtr); if(null == _glVendor) { if(DEBUG) { System.err.println("Warning: GL_VENDOR is NULL."); @@ -1387,7 +1408,7 @@ public abstract class GLContextImpl extends GLContext { } glVendor = _glVendor; - final String _glRenderer = glGetStringInt(GL.GL_RENDERER, _glGetString); + final String _glRenderer = glGetStringInt(GL.GL_RENDERER, glGetStringPtr); if(null == _glRenderer) { if(DEBUG) { System.err.println("Warning: GL_RENDERER is NULL."); @@ -1398,7 +1419,7 @@ public abstract class GLContextImpl extends GLContext { glRenderer = _glRenderer; glRendererLowerCase = glRenderer.toLowerCase(); - final String _glVersion = glGetStringInt(GL.GL_VERSION, _glGetString); + final String _glVersion = glGetStringInt(GL.GL_VERSION, glGetStringPtr); if(null == _glVersion) { // FIXME if(DEBUG) { @@ -1414,6 +1435,26 @@ public abstract class GLContextImpl extends GLContext { } /** + * Returns false if <code>glGetIntegerv</code> is inaccessible, otherwise queries major.minor + * version for given arrays. + * <p> + * If the GL query fails, major will be zero. + * </p> + */ + private final void getGLIntVersion(final int[] glIntMajor, final int[] glIntMinor) { + glIntMajor[0] = 0; // clear + glIntMinor[0] = 0; // clear + if( 0 == glGetIntegervPtr ) { + // should not be reached, since initGLRendererAndGLVersionStrings(..)'s failure should abort caller! + throw new InternalError("Not initialized: glGetString "+toHexString(glGetStringPtr)+", glGetIntegerv "+toHexString(glGetIntegervPtr)); + } else { + glGetIntegervInt(GL2ES3.GL_MAJOR_VERSION, glIntMajor, 0, glGetIntegervPtr); + glGetIntegervInt(GL2ES3.GL_MINOR_VERSION, glIntMinor, 0, glGetIntegervPtr); + } + } + + + /** * Returns null if version string is invalid, otherwise a valid instance. * <p> * Note: Non ARB ctx is limited to GL 3.0. @@ -1433,30 +1474,6 @@ public abstract class GLContextImpl extends GLContext { return null; } - /** - * Returns false if <code>glGetIntegerv</code> is inaccessible, otherwise queries major.minor - * version for given arrays. - * <p> - * If the GL query fails, major will be zero. - * </p> - */ - private final boolean getGLIntVersion(final int[] glIntMajor, final int[] glIntMinor) { - glIntMajor[0] = 0; // clear - final GLDynamicLookupHelper glDynLookupHelper = getDrawableImpl().getGLDynamicLookupHelper(); - final long _glGetIntegerv = glDynLookupHelper.dynamicLookupFunction("glGetIntegerv"); - if( 0 == _glGetIntegerv ) { - System.err.println("Error: Entry point to 'glGetIntegerv' is NULL."); - if(DEBUG) { - ExceptionUtils.dumpStack(System.err); - } - return false; - } else { - glGetIntegervInt(GL2ES3.GL_MAJOR_VERSION, glIntMajor, 0, _glGetIntegerv); - glGetIntegervInt(GL2ES3.GL_MINOR_VERSION, glIntMinor, 0, _glGetIntegerv); - return true; - } - } - protected final int getCtxOptions() { return ctxOptions; } @@ -1548,20 +1565,7 @@ public abstract class GLContextImpl extends GLContext { final VersionNumber hasGLVersionByInt; { final int[] glIntMajor = new int[] { 0 }, glIntMinor = new int[] { 0 }; - final boolean getGLIntVersionOK = getGLIntVersion(glIntMajor, glIntMinor); - if( !getGLIntVersionOK ) { - final String errMsg = "Fetching GL Integer Version failed. "+adevice+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null); - if( strictMatch ) { - // query mode .. simply fail - if(DEBUG) { - System.err.println("Warning: setGLFunctionAvailability: "+errMsg); - } - return false; - } else { - // unusable GL context - non query mode - hard fail! - throw new GLException(errMsg); - } - } + getGLIntVersion(glIntMajor, glIntMinor); hasGLVersionByInt = new VersionNumber(glIntMajor[0], glIntMinor[0], 0); } if (DEBUG) { @@ -2235,7 +2239,7 @@ public abstract class GLContextImpl extends GLContext { @Override public final boolean isFunctionAvailable(final String glFunctionName) { // Check GL 1st (cached) - if(null!=glProcAddressTable) { // null if this context wasn't not created + if( null != glProcAddressTable ) { // null if this context wasn't not created try { if( glProcAddressTable.isFunctionAvailable( glFunctionName ) ) { return true; @@ -2256,15 +2260,24 @@ public abstract class GLContextImpl extends GLContext { // dynamic function lookup at last incl name aliasing (not cached) final DynamicLookupHelper dynLookup = getDrawableImpl().getGLDynamicLookupHelper(); final String tmpBase = GLNameResolver.normalizeVEN(GLNameResolver.normalizeARB(glFunctionName, true), true); - boolean res = false; - final int variants = GLNameResolver.getFuncNamePermutationNumber(tmpBase); - for(int i = 0; !res && i < variants; i++) { - final String tmp = GLNameResolver.getFuncNamePermutation(tmpBase, i); - try { - res = dynLookup.isFunctionAvailable(tmp); - } catch (final Exception e) { } - } - return res; + return AccessController.doPrivileged(new PrivilegedAction<Boolean>() { + @Override + public Boolean run() { + boolean res = false; + dynLookup.claimAllLinkPermission(); + try { + final int variants = GLNameResolver.getFuncNamePermutationNumber(tmpBase); + for(int i = 0; !res && i < variants; i++) { + final String tmp = GLNameResolver.getFuncNamePermutation(tmpBase, i); + try { + res = dynLookup.isFunctionAvailable(tmp); + } catch (final Exception e) { } + } + } finally { + dynLookup.releaseAllLinkPermission(); + } + return Boolean.valueOf(res); + } } ).booleanValue(); } @Override diff --git a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java index e4d33b62c..744aefb32 100644 --- a/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java +++ b/src/jogl/classes/jogamp/opengl/util/av/impl/FFMPEGDynamicLibraryBundleInfo.java @@ -163,12 +163,11 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo { "swr_convert", }; + /** util, format, codec, device, avresample, swresample */ + private static final boolean[] libLoaded = new boolean[6]; private static final long[] symbolAddr = new long[symbolCount]; private static final boolean ready; private static final boolean libsUFCLoaded; - private static final boolean avresampleLoaded; // optional - private static final boolean swresampleLoaded; // optional - private static final boolean avdeviceLoaded; // optional static final VersionNumber avCodecVersion; static final VersionNumber avFormatVersion; static final VersionNumber avUtilVersion; @@ -187,19 +186,14 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo { // native ffmpeg media player implementation is included in jogl_desktop and jogl_mobile GLProfile.initSingleton(); boolean _ready = false; - /** util, format, codec, device, avresample, swresample */ - final boolean[] _loaded= new boolean[6]; /** util, format, codec, avresample, swresample */ final VersionNumber[] _versions = new VersionNumber[5]; try { - _ready = initSymbols(_loaded, _versions); + _ready = initSymbols(_versions); } catch (final Throwable t) { t.printStackTrace(); } - libsUFCLoaded = _loaded[LIB_IDX_UTI] && _loaded[LIB_IDX_FMT] && _loaded[LIB_IDX_COD]; - avdeviceLoaded = _loaded[LIB_IDX_DEV]; - avresampleLoaded = _loaded[LIB_IDX_AVR]; - swresampleLoaded = _loaded[LIB_IDX_SWR]; + libsUFCLoaded = libLoaded[LIB_IDX_UTI] && libLoaded[LIB_IDX_FMT] && libLoaded[LIB_IDX_COD]; avUtilVersion = _versions[0]; avFormatVersion = _versions[1]; avCodecVersion = _versions[2]; @@ -239,51 +233,52 @@ class FFMPEGDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo { } static boolean libsLoaded() { return libsUFCLoaded; } - static boolean avDeviceLoaded() { return avdeviceLoaded; } - static boolean avResampleLoaded() { return avresampleLoaded; } - static boolean swResampleLoaded() { return swresampleLoaded; } + static boolean avDeviceLoaded() { return libLoaded[LIB_IDX_DEV]; } + static boolean avResampleLoaded() { return libLoaded[LIB_IDX_AVR]; } + static boolean swResampleLoaded() { return libLoaded[LIB_IDX_SWR]; } static FFMPEGNatives getNatives() { return natives; } static boolean initSingleton() { return ready; } + private static final PrivilegedAction<DynamicLibraryBundle> privInitSymbolsAction = new PrivilegedAction<DynamicLibraryBundle>() { + @Override + public DynamicLibraryBundle run() { + final DynamicLibraryBundle dl = new DynamicLibraryBundle(new FFMPEGDynamicLibraryBundleInfo()); + for(int i=0; i<6; i++) { + libLoaded[i] = dl.isToolLibLoaded(i); + } + if( !libLoaded[LIB_IDX_UTI] || !libLoaded[LIB_IDX_FMT] || !libLoaded[LIB_IDX_COD] ) { + throw new RuntimeException("FFMPEG Tool library incomplete: [ avutil "+libLoaded[LIB_IDX_UTI]+", avformat "+libLoaded[LIB_IDX_FMT]+", avcodec "+libLoaded[LIB_IDX_COD]+"]"); + } + dl.claimAllLinkPermission(); + try { + for(int i = 0; i<symbolCount; i++) { + symbolAddr[i] = dl.dynamicLookupFunction(symbolNames[i]); + } + } finally { + dl.releaseAllLinkPermission(); + } + return dl; + } }; + /** * @param loaded 6: util, format, codec, device, avresample, swresample * @param versions 5: util, format, codec, avresample, swresample * @return */ - private static final boolean initSymbols(final boolean[] loaded, final VersionNumber[] versions) { + private static final boolean initSymbols(final VersionNumber[] versions) { for(int i=0; i<6; i++) { - loaded[i] = false; - } - final DynamicLibraryBundle dl = AccessController.doPrivileged(new PrivilegedAction<DynamicLibraryBundle>() { - @Override - public DynamicLibraryBundle run() { - return new DynamicLibraryBundle(new FFMPEGDynamicLibraryBundleInfo()); - } } ); - dl.toString(); - for(int i=0; i<6; i++) { - loaded[i] = dl.isToolLibLoaded(i); - } - if( !loaded[LIB_IDX_UTI] || !loaded[LIB_IDX_FMT] || !loaded[LIB_IDX_COD] ) { - throw new RuntimeException("FFMPEG Tool library incomplete: [ avutil "+loaded[LIB_IDX_UTI]+", avformat "+loaded[LIB_IDX_FMT]+", avcodec "+loaded[LIB_IDX_COD]+"]"); + libLoaded[i] = false; } if(symbolNames.length != symbolCount) { throw new InternalError("XXX0 "+symbolNames.length+" != "+symbolCount); } + AccessController.doPrivileged(privInitSymbolsAction); + // optional symbol name set final Set<String> optionalSymbolNameSet = new HashSet<String>(); optionalSymbolNameSet.addAll(Arrays.asList(optionalSymbolNames)); - // lookup - AccessController.doPrivileged(new PrivilegedAction<Object>() { - @Override - public Object run() { - for(int i = 0; i<symbolCount; i++) { - symbolAddr[i] = dl.dynamicLookupFunction(symbolNames[i]); - } - return null; - } } ); - // validate results boolean res = true; for(int i = 0; i<symbolCount; i++) { |