getsentry / getsentry/sentry-java

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

Offen
#6,120 2 Kommentare 0 Reaktionen 1 zugewiesene Person Beansprucht von @0xadam-brown Auf GitHub ansehen
Platform: Java Type: Bug
Vorherrschende Sprache
Kotlin
Sterne
1.4k
Forks
478
Ø Merge
2 T. 23 Std.
Gemergte PRs (30 T.)
67

Beschreibung

## 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.

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.