From f536d70504b56cfd2d9d2674830e6a9b0b49834d Mon Sep 17 00:00:00 2001 From: Meet Kalariya Date: Wed, 20 Nov 2024 23:58:37 -0500 Subject: [PATCH 1/4] Changes for issue 118 - Use readFully to Prevent Incomplete Reads in CursorLoader.java #118 --- .../main/java/com/jme3/cursors/plugins/CursorLoader.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/jme3-desktop/src/main/java/com/jme3/cursors/plugins/CursorLoader.java b/jme3-desktop/src/main/java/com/jme3/cursors/plugins/CursorLoader.java index 9c8af90e9..f28f40ab2 100644 --- a/jme3-desktop/src/main/java/com/jme3/cursors/plugins/CursorLoader.java +++ b/jme3-desktop/src/main/java/com/jme3/cursors/plugins/CursorLoader.java @@ -45,6 +45,8 @@ import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.nio.IntBuffer; import java.util.ArrayList; import javax.imageio.ImageIO; @@ -167,7 +169,9 @@ private JmeCursor loadCursor(InputStream inStream) throws IOException { if (leIn.readInt() == 0x6e6f6369) { // we have 'icon' // We have an icon and from this point on // the rest is only icons. - int icoLength = leIn.readInt(); + byte[] icoLengthBytes = new byte[4]; + leIn.readFully(icoLengthBytes); + int icoLength = ByteBuffer.wrap(icoLengthBytes).order(ByteOrder.LITTLE_ENDIAN).getInt(); ciDat.numImages = numIcons; icons = new ArrayList(numIcons); for (int i = 0; i < numIcons; i++) { From 2df0034ef8bcc3823eff320326b1ee9116b4708e Mon Sep 17 00:00:00 2001 From: Jayanth Apagundi Date: Thu, 21 Nov 2024 16:25:32 -0500 Subject: [PATCH 2/4] Software Vulnerability #120 changes --- .../jme3/app/state/VideoRecorderAppState.java | 74 ++++++++++++++++--- 1 file changed, 65 insertions(+), 9 deletions(-) diff --git a/jme3-desktop/src/main/java/com/jme3/app/state/VideoRecorderAppState.java b/jme3-desktop/src/main/java/com/jme3/app/state/VideoRecorderAppState.java index 153bf7fe3..6f564a752 100644 --- a/jme3-desktop/src/main/java/com/jme3/app/state/VideoRecorderAppState.java +++ b/jme3-desktop/src/main/java/com/jme3/app/state/VideoRecorderAppState.java @@ -171,33 +171,89 @@ public void setQuality(float quality) { @Override public void initialize(AppStateManager stateManager, Application app) { super.initialize(stateManager, app); - this.app = app; - this.oldTimer = app.getTimer(); - app.setTimer(new IsoTimer(framerate)); + + // Validate the input application instance + if (app == null) { + throw new IllegalArgumentException("Application instance cannot be null"); + } + + // Defensive copying: store only what is needed + this.oldTimer = app.getTimer(); // Keep the old timer + app.setTimer(new IsoTimer(framerate)); // Set the custom timer for this state + + RenderManager renderManager = app.getRenderManager(); + if (renderManager == null) { + throw new IllegalStateException("RenderManager is not initialized in the Application"); + } + + // Determine the file to write video to if none is specified if (file == null) { String filename = System.getProperty("user.home") + File.separator + "jMonkey-" + System.currentTimeMillis() / 1000 + ".avi"; file = new File(filename); } + processor = new VideoProcessor(); - List vps = app.getRenderManager().getPostViews(); + List viewPorts = renderManager.getPostViews(); - for (int i = vps.size() - 1; i >= 0; i-- ) { - lastViewPort = vps.get(i); + // Safely select the last enabled ViewPort + for (int i = viewPorts.size() - 1; i >= 0; i--) { + lastViewPort = viewPorts.get(i); if (lastViewPort.isEnabled()) { break; } } - lastViewPort.addProcessor(processor); + + // Attach the processor to the selected ViewPort + if (lastViewPort != null) { + lastViewPort.addProcessor(processor); + } else { + throw new IllegalStateException("No enabled ViewPort found to attach the VideoProcessor"); + } } +// public void initialize(AppStateManager stateManager, Application app) { +// super.initialize(stateManager, app); +// this.app = app; +// this.oldTimer = app.getTimer(); +// app.setTimer(new IsoTimer(framerate)); +// if (file == null) { +// String filename = System.getProperty("user.home") + File.separator + "jMonkey-" + System.currentTimeMillis() / 1000 + ".avi"; +// file = new File(filename); +// } +// processor = new VideoProcessor(); +// List vps = app.getRenderManager().getPostViews(); +// +// for (int i = vps.size() - 1; i >= 0; i-- ) { +// lastViewPort = vps.get(i); +// if (lastViewPort.isEnabled()) { +// break; +// } +// } +// lastViewPort.addProcessor(processor); +// } @Override public void cleanup() { - lastViewPort.removeProcessor(processor); - app.setTimer(oldTimer); + if (lastViewPort != null) { + lastViewPort.removeProcessor(processor); + } + + // Restore the old timer + if (app != null) { + app.setTimer(oldTimer); + } + initialized = false; file = null; + super.cleanup(); } +// public void cleanup() { +// lastViewPort.removeProcessor(processor); +// app.setTimer(oldTimer); +// initialized = false; +// file = null; +// super.cleanup(); +// } private class WorkItem { From 36ac0474fba3abef0a87c3d2b0720f3353e19de1 Mon Sep 17 00:00:00 2001 From: UtkaK18 <116825870+UtkaK18@users.noreply.github.com> Date: Sat, 30 Nov 2024 16:26:14 -0500 Subject: [PATCH 3/4] Update FbxImage.java --- .../fbx/java/com/jme3/scene/plugins/fbx/objects/FbxImage.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jme3-plugins/src/fbx/java/com/jme3/scene/plugins/fbx/objects/FbxImage.java b/jme3-plugins/src/fbx/java/com/jme3/scene/plugins/fbx/objects/FbxImage.java index 7ef329933..37d637764 100644 --- a/jme3-plugins/src/fbx/java/com/jme3/scene/plugins/fbx/objects/FbxImage.java +++ b/jme3-plugins/src/fbx/java/com/jme3/scene/plugins/fbx/objects/FbxImage.java @@ -111,7 +111,9 @@ private Image createImage() { Texture tex = null; try { tex = assetManager.loadTexture(new ContentTextureKey(scene.currentAssetInfo.getKey().getFolder() + filename, content)); - } catch(Exception e) {} + } catch(Exception e) { + throw new RuntimeException("Failed to load texture: " + filename, e); + } if(tex != null) image = tex.getImage(); } From 54e184dfd06d8d63541d1a957ad466370ccaba0a Mon Sep 17 00:00:00 2001 From: Minhazul Islam Date: Mon, 2 Dec 2024 06:14:52 -0500 Subject: [PATCH 4/4] The software vulnerability is a path traversal issue (CWE-23), where unauthorized user input from a command line argument is used as a file path. This allows attackers to manipulate the input to access files or directories outside the intended scope. If exploited, it can lead to unauthorized access to sensitive files or overwrite critical system files, posing risks such as information disclosure or arbitrary code execution. --- .../java/com/jme3/system/NativeLibraryLoader.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/jme3-desktop/src/main/java/com/jme3/system/NativeLibraryLoader.java b/jme3-desktop/src/main/java/com/jme3/system/NativeLibraryLoader.java index e315a3c8f..484757166 100644 --- a/jme3-desktop/src/main/java/com/jme3/system/NativeLibraryLoader.java +++ b/jme3-desktop/src/main/java/com/jme3/system/NativeLibraryLoader.java @@ -36,6 +36,7 @@ import java.net.URL; import java.net.URLConnection; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.HashMap; @@ -319,10 +320,18 @@ public static File[] getJarsWithNatives() { } public static void extractNativeLibraries(Platform platform, File targetDir) throws IOException { + File baseDir = new File("allowed/base/directory").getCanonicalFile(); + Path targetPath = targetDir.toPath().normalize(); + if (!targetPath.startsWith(baseDir.toPath())) { + throw new SecurityException("Path traversal attempt detected: " + targetDir.getPath()); + } for (Map.Entry lib : nativeLibraryMap.entrySet()) { if (lib.getValue().getPlatform() == platform) { if (!targetDir.exists()) { - targetDir.mkdirs(); + boolean dirsCreated = targetDir.mkdirs(); + if (!dirsCreated) { + throw new IOException("Failed to create target directory: " + targetDir.getPath()); + } } extractNativeLibrary(platform, lib.getValue().getName(), targetDir); }