From ca752c61c08eaa06458bdc6fa3cc724c09a62f77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Anic=CC=81?= Date: Thu, 11 Jul 2024 17:01:39 +0200 Subject: [PATCH] tls.Client: fix out of bounds panic When calculating how much ciphertext from the stream can fit into user and internal buffers we should also take into account ciphertext data which are already in internal buffer. Fixes: 15226 Tested with [this](https://github.com/ziglang/zig/issues/15226#issuecomment-2218809140). Using client with different read buffers until I, hopefully, understood what is happening. Not relevant to this fix, but this [part](https://github.com/ziglang/zig/blob/95d9292a7a09ed883e65510ec054619747315c48/lib/std/crypto/tls/Client.zig#L988-L991) is still mystery to me. Why we don't use free_size in buf_cap calculation. Seems like rudiment from previous implementation without iovec. --- lib/std/crypto/tls/Client.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/crypto/tls/Client.zig b/lib/std/crypto/tls/Client.zig index 9474953748..b68740bf6b 100644 --- a/lib/std/crypto/tls/Client.zig +++ b/lib/std/crypto/tls/Client.zig @@ -1012,7 +1012,7 @@ pub fn readvAdvanced(c: *Client, stream: anytype, iovecs: []const std.posix.iove // Cleartext capacity of output buffer, in records. Minimum one full record. const buf_cap = @max(cleartext_buf_len / max_ciphertext_len, 1); const wanted_read_len = buf_cap * (max_ciphertext_len + tls.record_header_len); - const ask_len = @max(wanted_read_len, cleartext_stack_buffer.len); + const ask_len = @max(wanted_read_len, cleartext_stack_buffer.len) - c.partial_ciphertext_end; const ask_iovecs = limitVecs(&ask_iovecs_buf, ask_len); const actual_read_len = try stream.readv(ask_iovecs); if (actual_read_len == 0) {