Skip to content

transport: Pool read buffers used by the HTTP/2 framer - #9032

Merged
arjan-bal merged 3 commits into
grpc:masterfrom
arjan-bal:h2-read-buffer-pool
Apr 22, 2026
Merged

transport: Pool read buffers used by the HTTP/2 framer#9032
arjan-bal merged 3 commits into
grpc:masterfrom
arjan-bal:h2-read-buffer-pool

Conversation

@arjan-bal

@arjan-bal arjan-bal commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

Problem

The HTTP/2 framer in gRPC uses a bufio.Reader with a 32KB buffer by default. When there are a large number of transports, these buffers consume significant memory, even when the transport is idle.

Solution

#8964 added a ReadyReader interface that allows non-memory-pinning reads. This PR replaces the standard bufio.Reader with a custom io.Reader implementation that uses pooled buffers and releases the buffer once all data is consumed.

To defer the re-allocation of the read buffer, the reader calls ReadOnReady on the underlying io.Reader. For this to work, the underlying io.Reader must implement either the ReadyReader interface or syscall.RawConn. If neither condition is met, the framer gracefully falls back to using the regular bufio.Reader.

Additional Changes:

  • The ALTS connection has been refactored to implement the ReadyReader interface.
  • The write buffer pools used by the framer are updated to use the mem.BufferPool interface, allowing the pools to be shared across both read and write operations.
  • Use syscall.Read instead of unix.Read to avoid triggering the race detector, see comment for details.
  • Add environment variable protection for the changes to allow fast rollback.

Benchmarks

In a real-world benchmark, where a GCS directpath client downloads a file in a loop, the average "in use" memory falls from 28.3MB to 21.3MB (-24%).

Local Benchmarks show no significant difference

❯ go run benchmark/benchresult/main.go streaming-before streaming-after                 
streaming-networkMode_Local-bufConn_false-keepalive_false-benchTime_2m0s-trace_false-latency_0s-kbps_0-MTU_0-maxConcurrentCa
lls_120-reqSize_1024B-respSize_1024B-compressor_off-channelz_false-preloader_false-clientReadBufferSize_-1-clientWriteBuffer
Size_-1-serverReadBufferSize_-1-serverWriteBufferSize_-1-sleepBetweenRPCs_0s-connections_1-recvBufferPool_simple-sharedWrite
Buffer_true
               Title       Before        After Percentage
            TotalOps     29981273     29966908    -0.05%
             SendOps            0            0      NaN%
             RecvOps            0            0      NaN%
            Bytes/op      4971.06      4971.41     0.00%
           Allocs/op        19.79        19.79     0.00%
             ReqT/op 2046721570.13 2045740919.47    -0.05%
            RespT/op 2046721570.13 2045740919.47    -0.05%
            50th-Lat    461.523µs    460.906µs    -0.13%
            90th-Lat    654.435µs    655.327µs     0.14%
            99th-Lat   1.225856ms   1.240984ms     1.23%
             Avg-Lat    478.845µs    479.553µs     0.15%
           GoVersion     go1.25.0     go1.25.0
         GrpcVersion   1.81.0-dev   1.81.0-dev

RELEASE NOTES:

  • transport: Pool HTTP/2 framer read buffers to reduce idle memory consumption. Currently limited to Linux for ALTS and non-encrypted transports (TCP, Unix). To disable, set GRPC_GO_EXPERIMENTAL_HTTP_FRAMER_READ_BUFFER_POOLING=false and report any issues.

@arjan-bal arjan-bal changed the title H2 read buffer pool transport: Pool read buffers in the HTTP/2 framer Apr 1, 2026
@codecov

codecov Bot commented Apr 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.00000% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.25%. Comparing base (f6304e9) to head (fc172d0).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
credentials/alts/internal/conn/record.go 75.00% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #9032      +/-   ##
==========================================
+ Coverage   80.55%   82.25%   +1.69%     
==========================================
  Files         413      413              
  Lines       33541    42322    +8781     
==========================================
+ Hits        27020    34810    +7790     
- Misses       4305     6105    +1800     
+ Partials     2216     1407     -809     
Files with missing lines Coverage Δ
internal/envconfig/envconfig.go 100.00% <ø> (+25.00%) ⬆️
internal/transport/http_util.go 95.87% <100.00%> (-2.06%) ⬇️
internal/transport/readyreader/raw_conn_linux.go 100.00% <100.00%> (ø)
internal/transport/readyreader/ready_reader.go 85.48% <100.00%> (+1.97%) ⬆️
credentials/alts/internal/conn/record.go 79.90% <75.00%> (-3.67%) ⬇️

... and 361 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@arjan-bal arjan-bal modified the milestone: 1.81 Release Apr 1, 2026
@arjan-bal arjan-bal added Type: Performance Performance improvements (CPU, network, memory, etc) Area: Transport Includes HTTP/2 client/server and HTTP server handler transports and advanced transport features. labels Apr 1, 2026
@arjan-bal
arjan-bal force-pushed the h2-read-buffer-pool branch from 24267f8 to b32d8ba Compare April 2, 2026 05:40
@arjan-bal arjan-bal closed this Apr 7, 2026
@arjan-bal

Copy link
Copy Markdown
Contributor Author

I'm splitting this PR into smaller PRs. I'll re-open this when the child PRs are merged.

arjan-bal added a commit that referenced this pull request Apr 8, 2026
### Background
In #9032, we will transition from standard `net.Conn.Read` methods to
`syscall` UNIX APIs to enable non-memory-pinning reads. Due to this
change, the Go race detector beings failing on tests that share state
between client and server goroutines without standard synchronization
primitives (mutexes, channels, etc.).

Because these tests rely on the network request itself as a memory
barrier, they are logically safe but technically racy from the Go
runtime's perspective. The standard `net.Conn` leverages Go's internal
network poller, which inadvertently provides the "happens-before" edges
the race detector looks for. Dropping down to raw syscalls bypasses
this, causing the detector to flag the accesses. (Minimal repro:
https://go.dev/play/p/yvEtBmLTOJ2)

### Solution
Introduce explicit synchronization to the affected tests. Tests now
properly coordinate shared state access between clients and servers
without relying on socket I/O timing.

RELEASE NOTES: N/A
arjan-bal added a commit that referenced this pull request Apr 14, 2026
…ll connection handling (#9035)

This PR eliminates per-call heap allocations in
`nonBlockingReader.ReadOnReady()`.

Previously, calling
[`RawConn.Read`](https://pkg.go.dev/syscall#RawConn.Read) with an inline
closure caused captured variables (and the closure itself) to escape to
the heap. To resolve this, we moved the closure's required state and
return values into fields on the `nonBlockingReader` struct. The state
is set before execution, and the results are read afterward. Because the
closure now only relies on the receiver's fields, we instantiate it
exactly once during `nonBlockingReader` construction and reuse it,
completely avoiding allocations on the hot path.

Additionally, this change updates the types for which non-blocking reads
are performed to the following:
* Unwrapped types created by `net.Dial`. This avoid reading encrypted
data from
[credentials.syscallConns](https://github.com/grpc/grpc-go/blob/74b3acd1a801570e1cefb28cf61620a4ef7c8ee2/internal/credentials/syscallconn.go#L37-L42).
* Types that already implement the `ReadyReader` interface themselves to
support encrypted connections.
 
These changes are a prerequisite for #9032.

## Benchmarks
#9032 uses `nonBlockingReader` instead of standard `net.Conn.Read` and
confirms zero increase in heap allocations for streaming RPCs.

RELEASE NOTES: N/A

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
arjan-bal added a commit that referenced this pull request Apr 16, 2026
This PR introduces a buffered `io.Reader` that automatically releases
its read buffer when empty. To optimize memory usage, the reader defers
buffer reallocation until data is available in the underlying
`readyreader.Reader` (achieved by calling `ReadOnReady`).

In a follow-up PR (#9032), the HTTP/2 framer will be updated to utilize
this new buffered reader whenever the underlying reader implements the
`readyreader.Reader` interface.

The implementation and associated tests are based on the [standard
library's](https://cs.opensource.google/go/go/+/refs/tags/go1.26.2:src/bufio/bufio.go;l=35).

RELEASE NOTES: N/A

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@arjan-bal arjan-bal reopened this Apr 21, 2026
@arjan-bal
arjan-bal force-pushed the h2-read-buffer-pool branch from c16297c to 8b8d538 Compare April 21, 2026 10:51
@arjan-bal

Copy link
Copy Markdown
Contributor Author

/gemini review

@arjan-bal arjan-bal changed the title transport: Pool read buffers in the HTTP/2 framer transport: Pool read buffers use by the HTTP/2 framer Apr 21, 2026
@arjan-bal
arjan-bal requested a review from easwars April 21, 2026 11:03

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements read buffer pooling for the HTTP framer and ALTS record protocol to reduce memory usage, particularly when subchannels are idle. It introduces a new environment variable GRPC_GO_EXPERIMENTAL_HTTP_FRAMER_READ_BUFFER_POOLING to control this feature. Key changes include updating the ALTS conn to support ReadOnReady, switching to syscall in readyreader to avoid race detector issues, and refactoring buffer pool management in http_util. Feedback was provided regarding the ALTS record protocol to ensure the returned pooled buffer's slice header is correctly updated to match the decrypted data length.

Comment thread credentials/alts/internal/conn/record.go
@arjan-bal arjan-bal changed the title transport: Pool read buffers use by the HTTP/2 framer transport: Pool read buffers used by the HTTP/2 framer Apr 21, 2026
Comment thread internal/transport/readyreader/ready_reader_ext_test.go Outdated
Comment thread internal/transport/readyreader/ready_reader_ext_test.go Outdated
Comment thread internal/transport/http_util.go
Comment thread internal/transport/http_util.go Outdated
Comment on lines +420 to +427
if !envconfig.EnableHTTPFramerReadBufferPooling {
return bufio.NewReaderSize(r, bufSize)
}
if rr := readyreader.NewNonBlocking(r); rr != nil {
readPool := getIOBufferPool(bufSize)
return readyreader.NewBuffered(rr, bufSize, readPool)
}
return bufio.NewReaderSize(r, bufSize)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Can we simplify this as:

- If env var is enabled **and** `r` supports non-blocking reads, create a `readyreader.NewBuffered` and return
- Fall though and create a regular bufio.Reader using `bufio.NewReaderSize`

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To check if r supports non-blocking reads, we have to call NewNonBlocking. When using feature flags, we should generally avoid invoking the protected code at all to prevent unexpected side effects (e.g., panics). Since Go evaluates if initialization statements before the condition, we cannot safely combine the assignment and the flag check on a single line. We would have to nest the conditionals to ensure the flag is evaluated first:

if envconfig.EnableHTTPFramerReadBufferPooling {
	if rr := readyreader.NewNonBlocking(r); rr != nil {
		readPool := getIOBufferPool(bufSize)
		return readyreader.NewBuffered(rr, bufSize, readPool)
	}
}

To avoid this nesting and keep the code flat, I opted to use an early return pattern instead. I'm fine the nesting style also.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nesting is what I meant, but I just wrote it as a single conditional in the pseudo code.

The only reason I ask for the nesting is because currently we have two code paths that do the same return bufio.NewReaderSize(r, bufSize). With the nesting, there will just be one of them. But it's not a big deal. Will leave it to you.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to nested style.

Comment thread internal/transport/http_util.go Outdated
@easwars easwars removed their assignment Apr 21, 2026
@arjan-bal
arjan-bal merged commit 29665f4 into grpc:master Apr 22, 2026
21 of 22 checks passed
@arjan-bal
arjan-bal deleted the h2-read-buffer-pool branch April 22, 2026 06:02
arjan-bal added a commit that referenced this pull request Apr 27, 2026
Original PRs: #9055, #9032

RELEASE NOTES:
* transport: Pool HTTP/2 framer read buffers to reduce idle memory
consumption. Currently limited to Linux for ALTS and non-encrypted
transports (TCP, Unix). To disable, set
`GRPC_GO_EXPERIMENTAL_HTTP_FRAMER_READ_BUFFER_POOLING=false` and report
any issues.

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
goingforstudying-ctrl added a commit to goingforstudying-ctrl/grpc-go that referenced this pull request Jun 21, 2026
…#9033)

### Background
In grpc#9032, we will transition from standard `net.Conn.Read` methods to
`syscall` UNIX APIs to enable non-memory-pinning reads. Due to this
change, the Go race detector beings failing on tests that share state
between client and server goroutines without standard synchronization
primitives (mutexes, channels, etc.).

Because these tests rely on the network request itself as a memory
barrier, they are logically safe but technically racy from the Go
runtime's perspective. The standard `net.Conn` leverages Go's internal
network poller, which inadvertently provides the "happens-before" edges
the race detector looks for. Dropping down to raw syscalls bypasses
this, causing the detector to flag the accesses. (Minimal repro:
https://go.dev/play/p/yvEtBmLTOJ2)

### Solution
Introduce explicit synchronization to the affected tests. Tests now
properly coordinate shared state access between clients and servers
without relying on socket I/O timing.

RELEASE NOTES: N/A
goingforstudying-ctrl added a commit to goingforstudying-ctrl/grpc-go that referenced this pull request Jun 21, 2026
…ll connection handling (grpc#9035)

This PR eliminates per-call heap allocations in
`nonBlockingReader.ReadOnReady()`.

Previously, calling
[`RawConn.Read`](https://pkg.go.dev/syscall#RawConn.Read) with an inline
closure caused captured variables (and the closure itself) to escape to
the heap. To resolve this, we moved the closure's required state and
return values into fields on the `nonBlockingReader` struct. The state
is set before execution, and the results are read afterward. Because the
closure now only relies on the receiver's fields, we instantiate it
exactly once during `nonBlockingReader` construction and reuse it,
completely avoiding allocations on the hot path.

Additionally, this change updates the types for which non-blocking reads
are performed to the following:
* Unwrapped types created by `net.Dial`. This avoid reading encrypted
data from
[credentials.syscallConns](https://github.com/grpc/grpc-go/blob/74b3acd1a801570e1cefb28cf61620a4ef7c8ee2/internal/credentials/syscallconn.go#L37-L42).
* Types that already implement the `ReadyReader` interface themselves to
support encrypted connections.
 
These changes are a prerequisite for grpc#9032.

## Benchmarks
grpc#9032 uses `nonBlockingReader` instead of standard `net.Conn.Read` and
confirms zero increase in heap allocations for streaming RPCs.

RELEASE NOTES: N/A

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
goingforstudying-ctrl added a commit to goingforstudying-ctrl/grpc-go that referenced this pull request Jun 21, 2026
This PR introduces a buffered `io.Reader` that automatically releases
its read buffer when empty. To optimize memory usage, the reader defers
buffer reallocation until data is available in the underlying
`readyreader.Reader` (achieved by calling `ReadOnReady`).

In a follow-up PR (grpc#9032), the HTTP/2 framer will be updated to utilize
this new buffered reader whenever the underlying reader implements the
`readyreader.Reader` interface.

The implementation and associated tests are based on the [standard
library's](https://cs.opensource.google/go/go/+/refs/tags/go1.26.2:src/bufio/bufio.go;l=35).

RELEASE NOTES: N/A

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
goingforstudying-ctrl added a commit to goingforstudying-ctrl/grpc-go that referenced this pull request Jun 21, 2026
## Problem
The HTTP/2 framer in gRPC uses a `bufio.Reader` with a 32KB buffer by
default. When there are a large number of transports, these buffers
consume significant memory, even when the transport is idle.

## Solution
grpc#8964 added a `ReadyReader` interface that allows non-memory-pinning
reads. This PR replaces the standard `bufio.Reader` with a custom
`io.Reader` implementation that uses pooled buffers and releases the
buffer once all data is consumed.

To defer the re-allocation of the read buffer, the reader calls
`ReadOnReady` on the underlying `io.Reader`. For this to work, the
underlying `io.Reader` must implement either the `ReadyReader` interface
or `syscall.RawConn`. If neither condition is met, the framer gracefully
falls back to using the regular `bufio.Reader`.

Additional Changes:
* The ALTS connection has been refactored to implement the `ReadyReader`
interface.
* The write buffer pools used by the framer are updated to use the
`mem.BufferPool` interface, allowing the pools to be shared across both
read and write operations.
* Use `syscall.Read` instead of `unix.Read` to avoid triggering the race
detector, see comment for details.
* Add environment variable protection for the changes to allow fast
rollback.

## Benchmarks
In a [real-world
benchmark](https://github.com/arjan-bal/custom-go-client-benchmark/tree/retry-dp),
where a GCS directpath client downloads a file in a loop, the average
"in use" memory falls from 28.3MB to 21.3MB (-24%).

Local Benchmarks show no significant difference
```
❯ go run benchmark/benchresult/main.go streaming-before streaming-after                 
streaming-networkMode_Local-bufConn_false-keepalive_false-benchTime_2m0s-trace_false-latency_0s-kbps_0-MTU_0-maxConcurrentCa
lls_120-reqSize_1024B-respSize_1024B-compressor_off-channelz_false-preloader_false-clientReadBufferSize_-1-clientWriteBuffer
Size_-1-serverReadBufferSize_-1-serverWriteBufferSize_-1-sleepBetweenRPCs_0s-connections_1-recvBufferPool_simple-sharedWrite
Buffer_true
               Title       Before        After Percentage
            TotalOps     29981273     29966908    -0.05%
             SendOps            0            0      NaN%
             RecvOps            0            0      NaN%
            Bytes/op      4971.06      4971.41     0.00%
           Allocs/op        19.79        19.79     0.00%
             ReqT/op 2046721570.13 2045740919.47    -0.05%
            RespT/op 2046721570.13 2045740919.47    -0.05%
            50th-Lat    461.523µs    460.906µs    -0.13%
            90th-Lat    654.435µs    655.327µs     0.14%
            99th-Lat   1.225856ms   1.240984ms     1.23%
             Avg-Lat    478.845µs    479.553µs     0.15%
           GoVersion     go1.25.0     go1.25.0
         GrpcVersion   1.81.0-dev   1.81.0-dev
```

RELEASE NOTES:
* transport: Pool HTTP/2 framer read buffers to reduce idle memory
consumption. Currently limited to Linux for ALTS and non-encrypted
transports (TCP, Unix). To disable, set
`GRPC_GO_EXPERIMENTAL_HTTP_FRAMER_READ_BUFFER_POOLING=false` and report
any issues.
nschloe pushed a commit to live-clones/forgejo that referenced this pull request Jul 23, 2026
…/forgejo) (#13580)

This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [google.golang.org/grpc](https://github.com/grpc/grpc-go) | `v1.79.3` → `v1.82.1` | ![age](https://developer.mend.io/api/mc/badges/age/go/google.golang.org%2fgrpc/v1.82.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/go/google.golang.org%2fgrpc/v1.79.3/v1.82.1?slim=true) |

---

### gRPC-Go: xDS RBAC and HTTP/2 Vulnerabilities
[GHSA-hrxh-6v49-42gf](GHSA-hrxh-6v49-42gf)

<details>
<summary>More information</summary>

#### Details
Multiple security vulnerabilities have been identified and addressed in grpc-go affecting the xDS RBAC authorization engine (internal/xds/rbac) and the HTTP/2 transport server implementation (internal/transport). These vulnerabilities could result in:

- Authorization Bypass (Fail-Open) when translating xDS RBAC policies containing `Metadata` or `RequestedServerName` fields.
- Denial of Service (High CPU Consumption) due to an HTTP/2 Rapid Reset mitigation bypass during client-initiated stream resets.
- Denial of Service (Server Panic) when parsing crafted xDS RBAC policies containing `NOT` rules around unsupported fields.

##### Impact
_What kind of vulnerability is it? Who is impacted?_

##### xDS RBAC Authorization Bypass via `Metadata` & `RequestedServerName` matchers

- Affected Component: xDS RBAC
- Impact: When building policy matchers for gRPC RBAC from xDS configurations, unsupported `permission` and `principal` rules (specifically `Metadata` and `RequestedServerName`) were silently ignored and treated as no-ops.
  - If an authorization policy relied purely on these matchers for access control, treating those rules as no-ops effectively removed the restrictions.
- If these unsupported rules were nested inside logical `NOT` rules (`Permission_NotRule` / `Principal_NotId`) or multi-condition `OR/AND` rules, silently dropping them changed the boolean logic flow of the authorization engine.

As a result, policy evaluation decisions could fail open, allowing unauthorized clients to access protected gRPC services or resources.

##### HTTP/2 Rapid Reset Mitigation Bypass / Denial of Service via Stream Aborts

- Affected Component: HTTP/2 transport
- Impact: Earlier mitigations in grpc-go for HTTP/2 Rapid Reset only applied threshold checks to items that directly resulted in control frames being written back to the wire, such as `SETTINGS` ACKs or server-initiated `RST_STREAM`s.

When a client initiated a rapid flood of stream creation (`HEADERS`) immediately followed by stream termination `RST_STREAM`, items queued up in the control buffer without counting against the transport response frame threshold. An attacker can repeatedly trigger this flood sequence to bypass reader blocking, resulting in high CPU usage, and Denial of Service (DoS).

##### Denial of Service (Panic) in xDS RBAC Engine via Unsupported Fields inside NOT Rules

- Affected Component: xDS RBAC
- Impact: The xDS RBAC policy translators recursively generate matchers for nested rules. When a `NOT` rule wrapped an unsupported or unhandled field (such as `SourcedMetadata`), the recursive step returned an empty matcher. This could result in a runtime panic when the RBAC engine attempts to authorize an incoming request.

An attacker or misconfigured/malicious xDS management server delivering an LDS/RDS update containing a `NOT` rule around an unhandled field causes the gRPC server process to crash immediately (CWE-248 / Denial of Service).

##### Patches
_Has the problem been patched? What versions should users upgrade to?_

All three issues have been fixed in `master` and will be released in 1.82.1 shortly.

##### Workarounds
_Is there a way for users to fix or remediate the vulnerability without upgrading?_

If upgrading grpc-go immediately is not possible, apply the following workarounds based on your deployment architecture:

* For xDS RBAC Vulnerabilities & Panics: Ensure that upstream xDS management servers do not push RBAC policies containing `Metadata`, `RequestedServerName`, or `NOT` rules wrapping unsupported fields (such as `SourcedMetadata`) to grpc-go servers.
* For HTTP/2 Rapid Reset DOS: Configure upstream reverse proxies or load balancers (such as Envoy) with strict HTTP/2 `max_concurrent_streams` limits and active rate limiting on `RST_STREAM` frequency per connection.

##### Severity

  | Vulnerability | Qualitative Severity | Approximate CVSS v3.1 Score | Primary Impact |
  | :--- | :--- | :--- | :--- |
  | **xDS RBAC Authorization Bypass** | **High** | `8.2` | Unauthorized Access / Fail-Open |
  | **HTTP/2 Rapid Reset DOS Bypass** | **High** | `7.5` | High CPU Consumption / Denial of Service |
  | **xDS RBAC Engine Server Panic** | **Medium** | `5.9` | Process Crash / Denial of Service |

#### Severity
- CVSS Score: 8.8 / 10 (High)
- Vector String: `CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:H/SC:N/SI:N/SA:N`

#### References
- [https://github.com/grpc/grpc-go/security/advisories/GHSA-hrxh-6v49-42gf](https://github.com/grpc/grpc-go/security/advisories/GHSA-hrxh-6v49-42gf)
- [https://github.com/grpc/grpc-go/pull/9236](https://github.com/grpc/grpc-go/pull/9236)
- [https://github.com/grpc/grpc-go/commit/4ea465d4ab98013f72a142fe0fc89c19770b2935](https://github.com/grpc/grpc-go/commit/4ea465d4ab98013f72a142fe0fc89c19770b2935)
- [https://github.com/grpc/grpc-go](https://github.com/grpc/grpc-go)
- [https://github.com/grpc/grpc-go/releases/tag/v1.82.1](https://github.com/grpc/grpc-go/releases/tag/v1.82.1)

This data is provided by [OSV](https://osv.dev/vulnerability/GHSA-hrxh-6v49-42gf) and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md)).
</details>

---

### Release Notes

<details>
<summary>grpc/grpc-go (google.golang.org/grpc)</summary>

### [`v1.82.1`](https://github.com/grpc/grpc-go/releases/tag/v1.82.1): Release 1.82.1

[Compare Source](grpc/grpc-go@v1.82.0...v1.82.1)

### Security

- server: Stop reading from the connection when flooded by HTTP/2 frames.  The default value for this limit is 100 frames, excluding DATA and HEADERS, and may be changed by setting environment variable `GRPC_GO_EXPERIMENTAL_CONTROL_BUFFER_THROTTLE_LIMIT`.
- xds/rbac: Support `Metadata` and `RequestedServerName` permissions matcher fields.  If present in a DENY rule, previously these would be ignored and fail-open.
- xds/rbac: Fix panic when parsing unsupported fields in `NotRule`/`NotId` permissions.
- xds/rbac: Support the deprecated `source_ip` principal identifier by treating it as equivalent to `direct_remote_ip`.

### [`v1.82.0`](https://github.com/grpc/grpc-go/releases/tag/v1.82.0): Release 1.82.0

[Compare Source](grpc/grpc-go@v1.81.1...v1.82.0)

### Behavior Changes

- server: Remove support for `GRPC_GO_EXPERIMENTAL_DISABLE_STRICT_PATH_CHECKING` environment varibale. Strict incoming RPC path validation (which has been the default since `v1.79.3`) can no longer be disabled. ([#&#8203;9112](grpc/grpc-go#9112))
- transport: Add environment variable to change the default max header list size from `16MB` to `8KB`. This may be enabled by setting `GRPC_GO_EXPERIMENTAL_ENABLE_8KB_DEFAULT_HEADER_LIST_SIZE=true`. This will be enabled by default in a subsequent release. ([#&#8203;9019](grpc/grpc-go#9019))
- balancer: Load Balancing policy registry is now case-sensitive.  Set `GRPC_GO_EXPERIMENTAL_CASE_SENSITIVE_BALANCER_REGISTRIES=false` (and file an issue) to revert to case-insensitive behavior. ([#&#8203;9017](grpc/grpc-go#9017))

### New Features

- experimental/stats: Expose a new API, `NewContextWithLabelCallback`, to register a callback that is invoked when telemetry labels are added. ([#&#8203;8877](grpc/grpc-go#8877))
  - Special Thanks: [@&#8203;seth-epps](https://github.com/seth-epps)
- client: Return a portion of the response body in the error message, when the client receives an unexpected non-gRPC HTTP response, to make debugging easier. ([#&#8203;8929](grpc/grpc-go#8929))
  - Special Thanks: [@&#8203;chengxilo](https://github.com/chengxilo)
- server: Add environment variable `GRPC_GO_SERVER_GOROUTINE_LABELS` that controls setting `runtime/pprof.Labels` on goroutines spawned by the server. Set `GRPC_GO_SERVER_GOROUTINE_LABELS=grpc.method=true` to add the `grpc.method` label on goroutines spawned to handle incoming requests. ([#&#8203;9082](grpc/grpc-go#9082))
  - Special Thanks: [@&#8203;dfinkel](https://github.com/dfinkel)

### Bug Fixes

- xds/server: Fix a memory leak of HTTP filter instances occurring when route configurations are updated in-place during a Route Discovery Service (RDS) update. ([#&#8203;9138](grpc/grpc-go#9138))
- grpc: In the deprecated `gzip` Compressor (used via the deprecated `WithCompressor` dial option), enforce the `MaxRecvMsgSize` limit on the decompressed message buffer, preventing excessive memory allocation from highly compressed payloads. ([#&#8203;9114](grpc/grpc-go#9114))
  - Special Thanks: [@&#8203;evilgensec](https://github.com/evilgensec)
- stats/opentelemetry: Record retry attempts, `grpc.previous-rpc-attempts`, at the call level and not the attempt level. ([#&#8203;8923](grpc/grpc-go#8923))
- encoding: Ensure `Close()` is always called on readers returned from `Compressor.Decompress` if possible. ([#&#8203;9135](grpc/grpc-go#9135))
- channelz: Fix the `LastMessageSentTimestamp` and `LastMessageReceivedTimestamp` fields in `SocketMetrics` to ensure they contain correct timestamp values. ([#&#8203;9109](grpc/grpc-go#9109))

### [`v1.81.1`](https://github.com/grpc/grpc-go/releases/tag/v1.81.1): Release 1.81.1

[Compare Source](grpc/grpc-go@v1.81.0...v1.81.1)

### Security

- xds/rbac: Fix a potential authorization bypass caused by incorrectly falling through URI/DNS SANs to Subject Distinguished Name (DN) when matching the authenticated principal name. With this fix, only the first non-empty identity source will be used, as per [gRFC A41](https://github.com/grpc/proposal/blob/master/A41-xds-rbac.md). ([#&#8203;9111](grpc/grpc-go#9111))
  - Special Thanks: [@&#8203;al4an444](https://github.com/al4an444)

### Bug Fixes

- otel: Segregate client and server RPC information used for metrics and traces, to avoid one overwriting the other. ([#&#8203;9081](grpc/grpc-go#9081))

### [`v1.81.0`](https://github.com/grpc/grpc-go/releases/tag/v1.81.0): Release 1.81.0

[Compare Source](grpc/grpc-go@v1.80.0...v1.81.0)

### Behavior Changes

- balancer/rls: Switch gauge metrics to asynchronous emission (once per collection cycle) to reduce telemetry noise and align with other gRPC language implementations. ([#&#8203;8808](grpc/grpc-go#8808))

### Dependencies

- Minimum supported Go version is now 1.25. ([#&#8203;8969](grpc/grpc-go#8969))

### Bug Fixes

- xds: Use the leaf cluster's security config for the TLS handshake instead of the aggregate cluster's config. ([#&#8203;8956](grpc/grpc-go#8956))
- transport: Send a `RST_STREAM` when receiving an `END_STREAM` when the stream is not already half-closed. ([#&#8203;8832](grpc/grpc-go#8832))
- xds: Fix ADS resource name validation to prevent a panic. ([#&#8203;8970](grpc/grpc-go#8970))

### New Features

- grpc/stats: Add support for custom labels in per-call metrics ([gRFC A108](https://github.com/grpc/proposal/blob/master/A108-otel-custom-per-call-label.md)). ([#&#8203;9008](grpc/grpc-go#9008))
- xds: Add support for Server Name Indication (SNI) and SAN validation ([gRFC A101](https://github.com/grpc/proposal/blob/master/A101-SNI-setting-and-SNI-SAN-validation.md)). Disabled by default. To enable, set `GRPC_EXPERIMENTAL_XDS_SNI=true` environment variable. ([#&#8203;9016](grpc/grpc-go#9016))
- xds: Add support to control which fields get propagated from ORCA backend metric reports to LRS load reports ([gRFC A85](https://github.com/grpc/proposal/blob/master/A85-lrs-custom-metrics-changes.md)). Disabled by default. To enable, set `GRPC_EXPERIMENTAL_XDS_ORCA_LRS_PROPAGATION=true`. ([#&#8203;9005](grpc/grpc-go#9005))
- xds: Add metrics to track xDS client connectivity and cached resource state ([gRFC A78](https://github.com/grpc/proposal/blob/master/A78-grpc-metrics-wrr-pf-xds.md)). ([#&#8203;8807](grpc/grpc-go#8807))
- stats/otel: Enhance `grpc.subchannel.disconnections` metric by adding disconnection reason to the `grpc.disconnect_error` label ([gRFC A94](https://github.com/grpc/proposal/blob/master/A94-subchannel-otel-metrics.md)). This provides granular insights into why subchannels are closing. ([#&#8203;8973](grpc/grpc-go#8973))
- mem: Add `mem.Buffer.Slice()` API to slice the buffer like a slice. ([#&#8203;8977](grpc/grpc-go#8977))
  - Special Thanks: [@&#8203;ash2k](https://github.com/ash2k)

### Performance Improvements

- alts: Pool read buffers to lower memory utilization when sockets are unreadable. ([#&#8203;8964](grpc/grpc-go#8964))
- transport: Pool HTTP/2 framer read buffers to reduce idle memory consumption. Currently limited to Linux for ALTS and non-encrypted transports (TCP, Unix). To disable, set `GRPC_GO_EXPERIMENTAL_HTTP_FRAMER_READ_BUFFER_POOLING=false` and report any issues. ([#&#8203;9032](grpc/grpc-go#9032))

### [`v1.80.0`](https://github.com/grpc/grpc-go/releases/tag/v1.80.0): Release 1.80.0

[Compare Source](grpc/grpc-go@v1.79.3...v1.80.0)

### Behavior Changes

- balancer: log a warning if a balancer is registered with uppercase letters, as balancer names should be lowercase. In a future release, balancer names will be treated as case-insensitive; see [#&#8203;5288](grpc/grpc-go#5288) for details. ([#&#8203;8837](grpc/grpc-go#8837))
- xds: update resource error handling and re-resolution logic ([#&#8203;8907](grpc/grpc-go#8907))
  - Re-resolve all `LOGICAL_DNS` clusters simultaneously when re-resolution is requested.
  - Fail all in-flight RPCs immediately upon receipt of listener or route resource errors, instead of allowing them to complete.

### Bug Fixes

- xds: support the LB policy configured in `LOGICAL_DNS` cluster resources instead of defaulting to `pick_first`. ([#&#8203;8733](grpc/grpc-go#8733))
- credentials/tls: perform per-RPC authority validation against the leaf certificate instead of the entire peer certificate chain. ([#&#8203;8831](grpc/grpc-go#8831))
- xds: enabling A76 ring hash endpoint keys no longer causes EDS resources with invalid proxy metadata to be NACKed when HTTP CONNECT (gRFC A86) is disabled. ([#&#8203;8875](grpc/grpc-go#8875))
- xds: validate that the sum of endpoint weights in a locality does not exceed the maximum `uint32` value. ([#&#8203;8899](grpc/grpc-go#8899))
  - Special Thanks: [@&#8203;RAVEYUS](https://github.com/RAVEYUS)
- xds: fix incorrect proto field access in the weighted round robin (WRR) configuration where `blackout_period` was used instead of `weight_expiration_period`. ([#&#8203;8915](grpc/grpc-go#8915))
  - Special Thanks: [@&#8203;gregbarasch](https://github.com/gregbarasch)
- xds/rbac: handle addresses with ports in IP matchers. ([#&#8203;8990](grpc/grpc-go#8990))

### New Features

- ringhash: enable gRFC A76 (endpoint hash keys and request hash headers) by default. ([#&#8203;8922](grpc/grpc-go#8922))

### Performance Improvements

- credentials/alts: pool write buffers to reduce memory allocations and usage. ([#&#8203;8919](grpc/grpc-go#8919))
- grpc: enable the use of pooled write buffers for buffering HTTP/2 frame writes by default. This reduces memory usage when connections are idle. Use the [WithSharedWriteBuffer](https://pkg.go.dev/google.golang.org/grpc#WithSharedWriteBuffer) dial option or the [SharedWriteBuffer](https://pkg.go.dev/google.golang.org/grpc#SharedWriteBuffer) server option to disable this feature. ([#&#8203;8957](grpc/grpc-go#8957))
- xds/priority: stop caching child LB policies removed from the configuration. This will help reduce memory and cpu usage when localities are constantly switching between priorities. ([#&#8203;8997](grpc/grpc-go#8997))
- mem: add a faster tiered buffer pool; use the experimental [mem.NewBinaryTieredBufferPool](https://pkg.go.dev/google.golang.org/grpc/mem@master#NewBinaryTieredBufferPool) function to create such pools. ([#&#8203;8775](grpc/grpc-go#8775))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - Between 12:00 AM and 03:59 AM (`* 0-3 * * *`)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNzIuMCIsInVwZGF0ZWRJblZlciI6IjQzLjI3Mi4wIiwidGFyZ2V0QnJhbmNoIjoidjE2LjAvZm9yZ2VqbyIsImxhYmVscyI6WyJkZXBlbmRlbmN5LXVwZ3JhZGUiLCJ0ZXN0L25vdC1uZWVkZWQiXX0=-->

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/13580
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.codeberg.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: Transport Includes HTTP/2 client/server and HTTP server handler transports and advanced transport features. Type: Performance Performance improvements (CPU, network, memory, etc)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants