This is an automated email from the ASF dual-hosted git repository.
ffang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/main by this push:
new f512d07036d Fix OpenScanHub findings: race conditions and resource
leaks (#2781)
f512d07036d is described below
commit f512d07036d232fc9c63a9e3fd0eacd83a4a3d19
Author: Roman Stepaniuk <[email protected]>
AuthorDate: Tue Jan 13 13:35:24 2026 +0100
Fix OpenScanHub findings: race conditions and resource leaks (#2781)
Co-authored-by: Roman Stepaniuk <[email protected]>
---
.../cxf/attachment/AttachmentDeserializer.java | 9 ++--
.../cxf/bus/extension/ExtensionManagerBus.java | 10 ++--
.../org/apache/cxf/common/util/StreamPrinter.java | 13 ++++--
.../apache/cxf/configuration/jsse/SSLUtils.java | 4 +-
.../src/main/java/httpsdemo/client/Client.java | 4 +-
.../main/java/demo/jaxrs/search/client/Client.java | 6 ++-
.../jaxws/client/DumpingClassLoaderCapturer.java | 4 +-
.../src/main/java/demo/hw/client/Get.java | 53 ++++++++++++++++++----
.../java/org/apache/cxf/aegis/AegisContext.java | 8 ++--
.../org/apache/cxf/javascript/cxf-utils.js | 2 +-
.../apache/cxf/jaxrs/client/spec/ClientImpl.java | 10 ++--
.../jwe/AbstractContentEncryptionAlgorithm.java | 30 ++++++------
.../security/oauth2/client/CodeAuthSupplier.java | 18 ++++----
.../apache/cxf/transport/servlet/CXFServlet.java | 4 +-
.../servicelist/ServiceListGeneratorServlet.java | 6 ++-
15 files changed, 115 insertions(+), 66 deletions(-)
diff --git
a/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializer.java
b/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializer.java
index 925fd98b230..d3b87411eac 100644
--- a/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializer.java
+++ b/core/src/main/java/org/apache/cxf/attachment/AttachmentDeserializer.java
@@ -244,10 +244,13 @@ public class AttachmentDeserializer {
if (!ads.isCached()) {
ads.cache(message);
}
- } else if (s.getInputStream() instanceof DelegatingInputStream) {
- cache((DelegatingInputStream) s.getInputStream());
} else {
- //assume a normal stream that is already cached
+ InputStream is = s.getInputStream();
+ if (is instanceof DelegatingInputStream) {
+ cache((DelegatingInputStream) is);
+ } else {
+ //assume a normal stream that is already cached
+ }
}
}
}
diff --git
a/core/src/main/java/org/apache/cxf/bus/extension/ExtensionManagerBus.java
b/core/src/main/java/org/apache/cxf/bus/extension/ExtensionManagerBus.java
index 4c12756d6ac..fd8ddd6a449 100644
--- a/core/src/main/java/org/apache/cxf/bus/extension/ExtensionManagerBus.java
+++ b/core/src/main/java/org/apache/cxf/bus/extension/ExtensionManagerBus.java
@@ -281,16 +281,16 @@ public class ExtensionManagerBus extends
AbstractBasicInterceptorProvider implem
}
public void shutdown(boolean wait) {
- if (state == BusState.SHUTTING_DOWN) {
- return;
+ synchronized (this) {
+ if (state == BusState.SHUTTING_DOWN) {
+ return;
+ }
+ state = BusState.SHUTTING_DOWN;
}
BusLifeCycleManager lifeCycleManager =
this.getExtension(BusLifeCycleManager.class);
if (null != lifeCycleManager) {
lifeCycleManager.preShutdown();
}
- synchronized (this) {
- state = BusState.SHUTTING_DOWN;
- }
destroyBeans();
synchronized (this) {
state = BusState.SHUTDOWN;
diff --git a/core/src/main/java/org/apache/cxf/common/util/StreamPrinter.java
b/core/src/main/java/org/apache/cxf/common/util/StreamPrinter.java
index fa8828764d5..564c64cc487 100644
--- a/core/src/main/java/org/apache/cxf/common/util/StreamPrinter.java
+++ b/core/src/main/java/org/apache/cxf/common/util/StreamPrinter.java
@@ -39,13 +39,12 @@ class StreamPrinter extends Thread {
@Override
public void run() {
- try {
+ try (InputStreamReader isr = new InputStreamReader(is);
+ BufferedReader br = new BufferedReader(isr)) {
PrintWriter pw = null;
if (os != null) {
pw = new PrintWriter(os);
}
- InputStreamReader isr = new InputStreamReader(is);
- BufferedReader br = new BufferedReader(isr);
String line = br.readLine();
while (line != null) {
if (pw != null) {
@@ -58,6 +57,14 @@ class StreamPrinter extends Thread {
}
} catch (IOException ioe) {
throw new RuntimeException(ioe);
+ } finally {
+ try {
+ if (is != null) {
+ is.close();
+ }
+ } catch (IOException e) {
+ // Ignore close exception
+ }
}
}
}
diff --git a/core/src/main/java/org/apache/cxf/configuration/jsse/SSLUtils.java
b/core/src/main/java/org/apache/cxf/configuration/jsse/SSLUtils.java
index 9c0e4e318d9..57a44026167 100644
--- a/core/src/main/java/org/apache/cxf/configuration/jsse/SSLUtils.java
+++ b/core/src/main/java/org/apache/cxf/configuration/jsse/SSLUtils.java
@@ -22,9 +22,9 @@ package org.apache.cxf.configuration.jsse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
@@ -196,7 +196,7 @@ public final class SSLUtils {
if (fileName == null) {
return null;
}
- Path path = FileSystems.getDefault().getPath(fileName);
+ Path path = Paths.get(fileName);
return Files.readAllBytes(path);
}
diff --git
a/distribution/src/main/release/samples/jax_rs/basic_https/src/main/java/httpsdemo/client/Client.java
b/distribution/src/main/release/samples/jax_rs/basic_https/src/main/java/httpsdemo/client/Client.java
index d6d4e56645c..918d44b077b 100644
---
a/distribution/src/main/release/samples/jax_rs/basic_https/src/main/java/httpsdemo/client/Client.java
+++
b/distribution/src/main/release/samples/jax_rs/basic_https/src/main/java/httpsdemo/client/Client.java
@@ -51,7 +51,9 @@ public final class Client {
String keyStoreLoc = "src/main/config/clientKeystore.jks";
KeyStore keyStore = KeyStore.getInstance("JKS");
- keyStore.load(new FileInputStream(keyStoreLoc),
"cspass".toCharArray());
+ try (FileInputStream fis = new FileInputStream(keyStoreLoc)) {
+ keyStore.load(fis, "cspass".toCharArray());
+ }
SSLContext sslcontext = SSLContexts.custom()
.loadTrustMaterial(keyStore, null)
diff --git
a/distribution/src/main/release/samples/jax_rs/search/src/main/java/demo/jaxrs/search/client/Client.java
b/distribution/src/main/release/samples/jax_rs/search/src/main/java/demo/jaxrs/search/client/Client.java
index 091b0812ed5..36f47e80122 100644
---
a/distribution/src/main/release/samples/jax_rs/search/src/main/java/demo/jaxrs/search/client/Client.java
+++
b/distribution/src/main/release/samples/jax_rs/search/src/main/java/demo/jaxrs/search/client/Client.java
@@ -20,6 +20,7 @@
package demo.jaxrs.search.client;
import java.io.IOException;
+import java.io.InputStream;
import org.apache.cxf.helpers.IOUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
@@ -99,7 +100,10 @@ public final class Client {
final HttpPost post = new HttpPost(url);
MultipartEntity entity = new MultipartEntity();
- byte[] bytes =
IOUtils.readBytesFromStream(Client.class.getResourceAsStream("/" + filename));
+ byte[] bytes;
+ try (InputStream is = Client.class.getResourceAsStream("/" +
filename)) {
+ bytes = IOUtils.readBytesFromStream(is);
+ }
entity.addPart(filename, new ByteArrayBody(bytes, filename));
post.setEntity(entity);
diff --git
a/distribution/src/main/release/samples/jaxws_graalvm_dynamic/client/src/main/java/demo/jaxws/client/DumpingClassLoaderCapturer.java
b/distribution/src/main/release/samples/jaxws_graalvm_dynamic/client/src/main/java/demo/jaxws/client/DumpingClassLoaderCapturer.java
index c713de90dbd..b7c819d25e6 100644
---
a/distribution/src/main/release/samples/jaxws_graalvm_dynamic/client/src/main/java/demo/jaxws/client/DumpingClassLoaderCapturer.java
+++
b/distribution/src/main/release/samples/jaxws_graalvm_dynamic/client/src/main/java/demo/jaxws/client/DumpingClassLoaderCapturer.java
@@ -35,8 +35,8 @@ public class DumpingClassLoaderCapturer implements
GeneratedClassClassLoaderCapt
private final Map<String, byte[]> classes = new ConcurrentHashMap<>();
public void dumpTo(File file) throws IOException {
- if (!file.exists())
- Files.createDirectories(file.toPath());{
+ if (!file.exists()) {
+ Files.createDirectories(file.toPath());
}
if (!file.isDirectory()) {
diff --git
a/distribution/src/main/release/samples/js_browser_client_simple/src/main/java/demo/hw/client/Get.java
b/distribution/src/main/release/samples/js_browser_client_simple/src/main/java/demo/hw/client/Get.java
index 4b79bc9d878..390fd05f52d 100644
---
a/distribution/src/main/release/samples/js_browser_client_simple/src/main/java/demo/hw/client/Get.java
+++
b/distribution/src/main/release/samples/js_browser_client_simple/src/main/java/demo/hw/client/Get.java
@@ -46,8 +46,14 @@ public final class Get {
System.out.println("Invoking server through HTTP GET to invoke sayHi");
InputStream in = httpConnection.getInputStream();
- StreamSource source = new StreamSource(in);
- printSource(source);
+ try {
+ StreamSource source = new StreamSource(in);
+ printSource(source);
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
// Sent HTTP GET request to invoke greetMe FAULT
target = "http://localhost:9000/SoapContext/SoapPort/greetMe/me/CXF";
@@ -58,14 +64,26 @@ public final class Get {
try {
in = httpConnection.getInputStream();
- source = new StreamSource(in);
- printSource(source);
+ try {
+ StreamSource source = new StreamSource(in);
+ printSource(source);
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
} catch (Exception e) {
System.err.println("GreetMe Fault: " + e.getMessage());
}
InputStream err = httpConnection.getErrorStream();
- source = new StreamSource(err);
- printSource(source);
+ if (err != null) {
+ try {
+ StreamSource source = new StreamSource(err);
+ printSource(source);
+ } finally {
+ err.close();
+ }
+ }
// Sent HTTP GET request to invoke greetMe
target =
"http://localhost:9000/SoapContext/SoapPort/greetMe/requestType/CXF";
@@ -75,8 +93,14 @@ public final class Get {
System.out.println("Invoking server through HTTP GET to invoke
greetMe");
in = httpConnection.getInputStream();
- source = new StreamSource(in);
- printSource(source);
+ try {
+ StreamSource source = new StreamSource(in);
+ printSource(source);
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
// Sent HTTP GET request to invoke pingMe
target = "http://localhost:9000/SoapContext/SoapPort/pingMe";
@@ -87,12 +111,21 @@ public final class Get {
try {
in = httpConnection.getInputStream();
+ if (in != null) {
+ in.close();
+ }
} catch (Exception e) {
System.out.println("PingMe fault raised");
}
err = httpConnection.getErrorStream();
- source = new StreamSource(err);
- printSource(source);
+ if (err != null) {
+ try {
+ StreamSource source = new StreamSource(err);
+ printSource(source);
+ } finally {
+ err.close();
+ }
+ }
}
private static void printSource(Source source) {
diff --git
a/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/AegisContext.java
b/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/AegisContext.java
index eddcbb9e4e2..5252c2d1e18 100644
--- a/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/AegisContext.java
+++ b/rt/databinding/aegis/src/main/java/org/apache/cxf/aegis/AegisContext.java
@@ -18,6 +18,8 @@
*/
package org.apache.cxf.aegis;
+import java.io.IOException;
+import java.io.InputStream;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
@@ -286,9 +288,9 @@ public class AegisContext {
}
private Document getSchemaDocument(String resourcePath) {
- try {
- return
StaxUtils.read(getClass().getResourceAsStream(resourcePath));
- } catch (XMLStreamException e) {
+ try (InputStream is = getClass().getResourceAsStream(resourcePath)) {
+ return StaxUtils.read(is);
+ } catch (XMLStreamException | IOException e) {
throw new RuntimeException(e);
}
}
diff --git
a/rt/javascript/javascript-rt/src/main/resources/org/apache/cxf/javascript/cxf-utils.js
b/rt/javascript/javascript-rt/src/main/resources/org/apache/cxf/javascript/cxf-utils.js
index 46d8864f356..cbf74f5b694 100644
---
a/rt/javascript/javascript-rt/src/main/resources/org/apache/cxf/javascript/cxf-utils.js
+++
b/rt/javascript/javascript-rt/src/main/resources/org/apache/cxf/javascript/cxf-utils.js
@@ -540,7 +540,7 @@ function org_apache_cxf_pad_string(string, len, pad, type) {
pad = typeof(pad) == 'string' ? pad : ' ';
if (type == org_apache_cxf_pad_string_PAD_BOTH) {
- string = org_apache_cxf_pad_sring(Math.floor(len / 2) +
string.length,
+ string = org_apache_cxf_pad_string(Math.floor(len / 2) +
string.length,
pad, org_apache_cxf_pad_string_PAD_LEFT);
return (org_apache_cxf_pad_string(Math.ceil(len / 2) +
string.length,
pad, org_apache_cxf_pad_string_PAD_RIGHT));
diff --git
a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientImpl.java
b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientImpl.java
index 48f5b9947ce..a6ed934d270 100644
---
a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientImpl.java
+++
b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/ClientImpl.java
@@ -67,6 +67,7 @@ public class ClientImpl implements Client {
private Configurable<Client> configImpl;
private TLSConfiguration secConfig;
private boolean closed;
+ private final Object baseClientsLock = new Object();
private Set<WebClient> baseClients =
Collections.synchronizedSet(Collections.newSetFromMap(new
WeakHashMap<WebClient, Boolean>()));
@@ -78,16 +79,15 @@ public class ClientImpl implements Client {
@Override
public void close() {
- if (!closed) {
- synchronized (baseClients) {
+ synchronized (baseClientsLock) {
+ if (!closed) {
for (WebClient wc : baseClients) {
wc.close();
}
+ baseClients = null;
+ closed = true;
}
- baseClients = null;
- closed = true;
}
-
}
@Override
diff --git
a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionAlgorithm.java
b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionAlgorithm.java
index 21ae4c70ea0..a5a46d4fb5d 100644
---
a/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionAlgorithm.java
+++
b/rt/rs/security/jose-parent/jose/src/main/java/org/apache/cxf/rs/security/jose/jwe/AbstractContentEncryptionAlgorithm.java
@@ -51,24 +51,24 @@ public abstract class AbstractContentEncryptionAlgorithm
extends AbstractContent
public byte[] getContentEncryptionKey(JweHeaders headers) {
final byte[] theCek;
- if (cek == null) {
- String algoJava = getAlgorithm().getJavaName();
- SecretKey secretKey =
CryptoUtils.getSecretKey(AlgorithmUtils.stripAlgoProperties(algoJava),
- getContentEncryptionKeySize(headers));
- theCek = secretKey.getEncoded();
- if (generateCekOnce) {
- synchronized (this) {
+ synchronized (this) {
+ if (cek == null) {
+ String algoJava = getAlgorithm().getJavaName();
+ SecretKey secretKey =
CryptoUtils.getSecretKey(AlgorithmUtils.stripAlgoProperties(algoJava),
+ getContentEncryptionKeySize(headers));
+ theCek = secretKey.getEncoded();
+ if (generateCekOnce) {
cek = theCek;
}
+ // Clean the key after we're done with it
+ try {
+ secretKey.destroy();
+ } catch (DestroyFailedException e) {
+ // ignore
+ }
+ } else {
+ theCek = cek;
}
- // Clean the key after we're done with it
- try {
- secretKey.destroy();
- } catch (DestroyFailedException e) {
- // ignore
- }
- } else {
- theCek = cek;
}
return theCek;
}
diff --git
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/CodeAuthSupplier.java
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/CodeAuthSupplier.java
index efca0ee42c3..b923e9f5095 100644
---
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/CodeAuthSupplier.java
+++
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/CodeAuthSupplier.java
@@ -42,16 +42,14 @@ public class CodeAuthSupplier implements HttpAuthSupplier {
URI currentURI,
Message message,
String fullHeader) {
- if (code != null) {
- synchronized (tokenSupplier) {
- if (tokenSupplier.getClientAccessToken().getTokenKey() ==
null) {
- WebClient wc =
tokenSupplier.createAccessTokenServiceClient();
- ClientAccessToken at = OAuthClientUtils.getAccessToken(wc,
-
tokenSupplier.getConsumer(),
- new
AuthorizationCodeGrant(code));
- code = null;
- tokenSupplier.setClientAccessToken(at);
- }
+ synchronized (tokenSupplier) {
+ if (code != null &&
tokenSupplier.getClientAccessToken().getTokenKey() == null) {
+ WebClient wc = tokenSupplier.createAccessTokenServiceClient();
+ ClientAccessToken at = OAuthClientUtils.getAccessToken(wc,
+ tokenSupplier.getConsumer(),
+ new
AuthorizationCodeGrant(code));
+ code = null;
+ tokenSupplier.setClientAccessToken(at);
}
}
return tokenSupplier.getAuthorization(authPolicy, currentURI, message,
fullHeader);
diff --git
a/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/CXFServlet.java
b/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/CXFServlet.java
index d8e3f26b280..a64da06e7ee 100644
---
a/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/CXFServlet.java
+++
b/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/CXFServlet.java
@@ -61,10 +61,8 @@ public class CXFServlet extends CXFNonSpringServlet
String configLocation =
servletConfig.getInitParameter("config-location");
if (configLocation == null) {
- try {
- InputStream is =
servletConfig.getServletContext().getResourceAsStream("/WEB-INF/cxf-servlet.xml");
+ try (InputStream is =
servletConfig.getServletContext().getResourceAsStream("/WEB-INF/cxf-servlet.xml"))
{
if (is != null && is.available() > 0) {
- is.close();
configLocation = "/WEB-INF/cxf-servlet.xml";
}
} catch (Exception ex) {
diff --git
a/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/servicelist/ServiceListGeneratorServlet.java
b/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/servicelist/ServiceListGeneratorServlet.java
index cff4311be29..9e133429851 100644
---
a/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/servicelist/ServiceListGeneratorServlet.java
+++
b/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/servicelist/ServiceListGeneratorServlet.java
@@ -84,8 +84,10 @@ public class ServiceListGeneratorServlet extends HttpServlet
{
if ("HEAD".equals(request.getMethod())) {
return;
}
- if (bus == null) {
- bus = BusFactory.getDefaultBus(false);
+ synchronized (this) {
+ if (bus == null) {
+ bus = BusFactory.getDefaultBus(false);
+ }
}
final ServiceListWriter serviceListWriter;
if ("false".equals(request.getParameter("formatted"))) {