From 8a2e9959f3bcba4d26d7a6bfd8e3cedebf2fcb18 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 13 Jun 2026 19:48:23 +0000 Subject: [PATCH] Fix USO_UNSAFE_STATIC_METHOD_SYNCHRONIZATION in LlamaLoader.initialize() Synchronize on a private static lock object instead of the LlamaLoader class's intrinsic lock, so untrusted code that can reach the public LlamaLoader type cannot acquire the same monitor and interfere with native-library initialization. --- .../ladenthin/llama/loader/LlamaLoader.java | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/main/java/net/ladenthin/llama/loader/LlamaLoader.java b/src/main/java/net/ladenthin/llama/loader/LlamaLoader.java index 30882ba9..cba29344 100644 --- a/src/main/java/net/ladenthin/llama/loader/LlamaLoader.java +++ b/src/main/java/net/ladenthin/llama/loader/LlamaLoader.java @@ -44,6 +44,16 @@ @ToString public class LlamaLoader { + /** + * Private monitor guarding {@link #initialize()}. Synchronizing on this + * dedicated object instead of {@code LlamaLoader.class} keeps the lock + * private to this class, so untrusted code that can reach the public + * {@code LlamaLoader} type cannot acquire the same intrinsic lock and + * interfere with library initialization (SpotBugs + * {@code USO_UNSAFE_STATIC_METHOD_SYNCHRONIZATION}). + */ + private static final Object INITIALIZE_LOCK = new Object(); + private static boolean extracted = false; private static final LlamaSystemProperties systemProperties = new LlamaSystemProperties(); private static final NativeLibraryPermissionSetter permissionSetter = new NativeLibraryPermissionSetter(System.err); @@ -63,22 +73,24 @@ private LlamaLoader() {} /** * Loads the llama and jllama shared libraries */ - public static synchronized void initialize() { - // only cleanup before the first extract - if (!extracted) { - cleanup(); - } - if ("Mac".equals(OSInfo.getOSName())) { - String nativeDirName = getNativeResourcePath(); - String tempFolder = getTempDir().getAbsolutePath(); - System.out.println(nativeDirName); - Path metalFilePath = extractFile(nativeDirName, "ggml-metal.metal", tempFolder); - if (metalFilePath == null) { - System.err.println("'ggml-metal.metal' not found"); + public static void initialize() { + synchronized (INITIALIZE_LOCK) { + // only cleanup before the first extract + if (!extracted) { + cleanup(); + } + if ("Mac".equals(OSInfo.getOSName())) { + String nativeDirName = getNativeResourcePath(); + String tempFolder = getTempDir().getAbsolutePath(); + System.out.println(nativeDirName); + Path metalFilePath = extractFile(nativeDirName, "ggml-metal.metal", tempFolder); + if (metalFilePath == null) { + System.err.println("'ggml-metal.metal' not found"); + } } + loadNativeLibrary("jllama"); + extracted = true; } - loadNativeLibrary("jllama"); - extracted = true; } /**