VYPR
Low severity2.1GHSA Advisory· Published May 28, 2026· Updated May 28, 2026

opentelemetry-go's Schema ParseFile leaks file descriptors on each parse

CVE-2026-45287

Description

Summary

go.opentelemetry.io/otel/schema/v1.0 and go.opentelemetry.io/otel/schema/v1.1 leaks one file descriptor on each successful ParseFile call. ParseFile opens the schema file and passes it to Parse without closing it; repeated parsing in a long-running process can exhaust the process file descriptor limit and cause denial of service. The severity is low because exploitation depends on a consuming application exposing repeated schema parsing to an attacker-controlled path.

Introduced in commit: e72a235

Details

In schema/v1.0/parser.go:41-47, ParseFile opens the requested schema path with os.Open and then returns Parse(file) without a defer file.Close() or other close path:

file, err := os.Open(schemaFilePath)
if err != nil {
	return nil, err
}
return Parse(file)

The validation evidence also identifies schema/v1.0/parser.go:50-73: Parse accepts an io.Reader, decodes from it, and does not close it. Ownership of the opened file is therefore not transferred to Parse, leaving the descriptor open until the Go runtime eventually finalizes the file object. With repeated ParseFile calls, descriptors can accumulate until the process receives EMFILE / "too many open files".

PoC

validation-artifact.zip

The local artifact validation-artifact.zip contains:

  • leak_poc.go: PoC source that repeatedly calls schema.ParseFile("schema/v1.0/testdata/valid-example.yaml") and prints /proc/self/fd counts.
  • LEAK_POC_README.txt: reproduction notes.
  • leak_poc_run.log: captured attempted run; the local offline environment failed before execution because Go module download from proxy.golang.org was forbidden.

Reproduce from the root of a checkout of pellared/opentelemetry-go at commit e72a235 with Go module dependencies already available:

/bin/sh -c 'ulimit -n 256; GOGC=off go run leak_poc.go'

Configuration:

  • File descriptor soft limit: 256
  • Garbage collection: disabled with GOGC=off so leaked descriptors are not reclaimed during the loop
  • Schema file: schema/v1.0/testdata/valid-example.yaml

Expected output is increasing descriptor counts followed by an EMFILE failure, for example:

iter 0 fds 7
iter 50 fds 57
iter 100 fds 107
...
panic: iteration 248: open schema/v1.0/testdata/valid-example.yaml: too many open files

The exact initial descriptor count and failing iteration can vary by OS and process state.

Impact

This is a file descriptor resource leak leading to availability loss. Applications that call schema.ParseFile repeatedly, especially through a runtime reload or request-controlled path, can exhaust their process file descriptor table and fail subsequent file, socket, or other descriptor operations. Impact is limited to denial of service of the consuming process; the evidence does not show confidentiality or integrity impact.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

OpenTelemetry Go schema ParseFile leaks a file descriptor on each call, potentially exhausting process limits and causing DoS.

Vulnerability

go.opentelemetry.io/otel/schema/v1.0 and go.opentelemetry.io/otel/schema/v1.1 leak one file descriptor on each successful ParseFile call. In schema/v1.0/parser.go, ParseFile opens the schema file with os.Open and passes the file handle to Parse without a defer file.Close() or any other close mechanism. The Parse function accepts an io.Reader and does not close it, so ownership of the opened file is not transferred. Repeated ParseFile calls in a long-running process cause file descriptors to accumulate until the process reaches its file descriptor limit and fails with EMFILE / "too many open files". The affected versions are those based on commit e72a235.

Exploitation

An attacker does not require special network position or authentication beyond the ability to supply a file path that an application passes to ParseFile. The exploit depends on a consuming application exposing repeated schema parsing to an attacker-controlled path. With garbage collection disabled (GOGC=off) and a typical file descriptor soft limit (e.g., 256), a loop of 257 or more ParseFile calls will exhaust the limit and cause the denial of service. The proof-of-concept artifact (validation-artifact.zip) demonstrates repeated calls to schema.ParseFile("schema/v1.0/testdata/valid-example.yaml") and tracks increasing descriptor counts via /proc/self/fd. [1][2]

Impact

An attacker can cause a denial of service (DoS) by exhausting the process's file descriptor limit. The impact is limited to availability; there is no information disclosure, file write, or code execution.

Mitigation

As of the publication date (2026-05-28), no fixed version has been released. The advisory recommends that applications limit exposure to untrusted schema file paths and monitor file descriptor usage. The vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. [1][2]

AI Insight generated on May 28, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

2

Patches

0

No patches discovered yet.

Vulnerability mechanics

Root cause

"Missing `file.Close()` in `ParseFile` after opening the schema file, causing one file descriptor to leak on each successful call."

Attack vector

An attacker who can control or influence the schema file path passed to `ParseFile` can cause repeated parsing calls in a long-running process [ref_id=1][ref_id=2]. Each successful call leaks one file descriptor because `ParseFile` opens the file but never closes it [ref_id=1][ref_id=2]. Over many iterations, leaked descriptors accumulate until the process hits the system file descriptor limit (`EMFILE`), causing denial of service on subsequent file, socket, or other descriptor operations [ref_id=1][ref_id=2]. The attack requires a consuming application to expose repeated schema parsing to an attacker-controlled path, which limits severity to low [ref_id=1][ref_id=2].

Affected code

The vulnerability is in `schema/v1.0/parser.go` lines 41-47, where `ParseFile` opens a schema file with `os.Open` and returns `Parse(file)` without a `defer file.Close()` [ref_id=1][ref_id=2]. The `Parse` function (lines 50-73) accepts an `io.Reader` and does not close it, so ownership of the file descriptor is never transferred [ref_id=1][ref_id=2]. The bug was introduced in commit `e72a235` [ref_id=1][ref_id=2].

What the fix does

No patch is included in the bundle. The advisory recommends adding a `defer file.Close()` after `os.Open` in `ParseFile` (or otherwise ensuring the file descriptor is closed before `Parse` returns) [ref_id=1][ref_id=2]. Because `Parse` accepts a generic `io.Reader` and does not close it, the fix must be applied at the `ParseFile` call site where the file handle is owned [ref_id=1][ref_id=2].

Preconditions

  • configThe consuming application must call schema.ParseFile repeatedly, e.g., on a runtime reload or request-controlled path
  • inputThe attacker must be able to influence or trigger the schema file path passed to ParseFile
  • networkThe process must run long enough or parse enough times to exhaust the file descriptor limit

Reproduction

From the root of a checkout of `pellared/opentelemetry-go` at commit `e72a235` with Go module dependencies available, run: `/bin/sh -c 'ulimit -n 256; GOGC=off go run leak_poc.go'` [ref_id=1][ref_id=2]. The PoC repeatedly calls `schema.ParseFile("schema/v1.0/testdata/valid-example.yaml")` and prints `/proc/self/fd` counts [ref_id=1][ref_id=2]. Expected output shows increasing descriptor counts (e.g., iter 0 fds 7, iter 50 fds 57) followed by a panic: `iteration 248: open schema/v1.0/testdata/valid-example.yaml: too many open files` [ref_id=1][ref_id=2].

Generated on May 28, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

2

News mentions

0

No linked articles in our index yet.