getsentry / getsentry/sentry-java

ManifestVersionReader leaks a ZipFile Inflater per JAR (openStream never closed)

Abierto
#6,120 2 comentarios 0 reacciones 1 asignado Reclamado por @0xadam-brown Ver en GitHub
Platform: Java Type: Bug
Lenguaje dominante
Kotlin
Estrellas
1.4k
Forks
478
Merge medio
2 d 23 h
PR fusionados (30 d)
67

Descripción

## Description

`ManifestVersionReader.readManifestFiles()` enumerates every `META-INF/MANIFEST.MF` on the classpath and passes `URL.openStream()` into `new Manifest(InputStream)` **without closing the stream**.

`java.util.jar.Manifest(InputStream)` reads the stream and does not close it. For `jar:` URLs that stream is a `ZipFileInflaterInputStream`. Closing it is what calls `ZipFile$CleanableResource.releaseInflater()`. If it is never closed, each JAR leaves a live `java.util.zip.Inflater` (~64 KiB zlib window).

This still matches [main](https://github.com/getsentry/sentry-java/blob/main/sentry/src/main/java/io/sentry/internal/ManifestVersionReader.java) and 8.41.0 / 8.52.0.

## Call site

```java
final Enumeration resources =
ClassLoader.getSystemClassLoader().getResources("META-INF/MANIFEST.MF");
while (resources.hasMoreElements()) {
try {
final Manifest manifest = new Manifest(resources.nextElement().openStream());
// ...
} catch (Exception e) {
// ignore
}
}
```

Triggered from `ManifestVersionDetector.checkForMixedVersions()` → `InitUtil.shouldInit()` → `Sentry.init()`.

## Observed

Compose Desktop / packaged JVM app with ~80 JARs on the classpath (`sentry-java` **8.41.0**):

- `GC.class_histogram`: **168** live `java.util.zip.Inflater`
- async-profiler `event=java.util.zip.Inflater.` from process start: **79 / 174** constructors (45%) are

```
java.util.zip.Inflater.
java.util.zip.ZipFile$CleanableResource.getInflater
java.util.zip.ZipFile$ZipFileInflaterInputStream.
java.util.zip.ZipFile.getInputStream
java.util.jar.JarFile.getBytes
java.util.jar.JarFile.checkForSpecialAttributes
java.util.jar.JarFile.isMultiRelease
java.util.jar.JarFile.getEntry
sun.net.www.protocol.jar.URLJarFile.getEntry
sun.net.www.protocol.jar.JarURLConnection.connect
sun.net.www.protocol.jar.JarURLConnection.getInputStream
java.net.URL.openStream
io.sentry.internal.ManifestVersionReader.readManifestFiles
io.sentry.ManifestVersionDetector.checkForMixedVersions
io.sentry.util.InitUtil.shouldInit
io.sentry.Sentry.init
```

## Suggested fix

```java
try (InputStream is = resources.nextElement().openStream()) {
final Manifest manifest = new Manifest(is);
// existing attribute handling
} catch (Exception e) {
// ignore
}
```

`Manifest` does not take ownership of the stream, so try-with-resources is required even on the success path.

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.