getsentry / getsentry/sentry-java

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

Đang mở
#6,120 2 bình luận 0 reaction 1 người được giao Được @0xadam-brown nhận Xem trên GitHub
Platform: Java Type: Bug
Ngôn ngữ chính
Kotlin
Star
1.4k
Fork
478
Merge trung bình
2 ngày 23 giờ
Pull request đã merge (30 ngày)
67

Mô tả

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

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.