https://github.com/python/cpython/commit/0efd679a6ce3b57ec3c5cd07f795d36170629dc6
commit: 0efd679a6ce3b57ec3c5cd07f795d36170629dc6
branch: main
author: Maurycy Pawłowski-Wieroński <[email protected]>
committer: pablogsal <[email protected]>
date: 2026-04-28T00:06:23+01:00
summary:
gh-148252: Avoid overflow in `_remote_debugging` binary reader bounds checks
(#148972)
files:
A Misc/NEWS.d/next/Security/2026-04-24-23-15-42.gh-issue-148252.8BLmzd.rst
M Modules/_remote_debugging/binary_io.h
M Modules/_remote_debugging/binary_io_reader.c
M Modules/_remote_debugging/binary_io_writer.c
diff --git
a/Misc/NEWS.d/next/Security/2026-04-24-23-15-42.gh-issue-148252.8BLmzd.rst
b/Misc/NEWS.d/next/Security/2026-04-24-23-15-42.gh-issue-148252.8BLmzd.rst
new file mode 100644
index 00000000000000..531ea2348ffdef
--- /dev/null
+++ b/Misc/NEWS.d/next/Security/2026-04-24-23-15-42.gh-issue-148252.8BLmzd.rst
@@ -0,0 +1,3 @@
+Fixed string table and sample record bounds checks in :mod:`!_remote_debugging`
+when decoding certain ``.pyb`` inputs on 32-bit builds. Patch by Maurycy
+Pawłowski-Wieroński.
diff --git a/Modules/_remote_debugging/binary_io.h
b/Modules/_remote_debugging/binary_io.h
index d90546078bf68c..18f989f672e103 100644
--- a/Modules/_remote_debugging/binary_io.h
+++ b/Modules/_remote_debugging/binary_io.h
@@ -61,6 +61,7 @@ extern "C" {
#define HDR_SIZE_COMPRESSION 4
#define FILE_HEADER_SIZE (HDR_OFF_COMPRESSION + HDR_SIZE_COMPRESSION)
#define FILE_HEADER_PLACEHOLDER_SIZE 64
+#define SAMPLE_HEADER_FIXED_SIZE (sizeof(uint64_t) + sizeof(uint32_t) + 1)
static_assert(FILE_HEADER_SIZE <= FILE_HEADER_PLACEHOLDER_SIZE,
"FILE_HEADER_SIZE exceeds FILE_HEADER_PLACEHOLDER_SIZE");
diff --git a/Modules/_remote_debugging/binary_io_reader.c
b/Modules/_remote_debugging/binary_io_reader.c
index aca93e9cb1a30e..6c32ef70ac3f65 100644
--- a/Modules/_remote_debugging/binary_io_reader.c
+++ b/Modules/_remote_debugging/binary_io_reader.c
@@ -258,7 +258,7 @@ reader_parse_string_table(BinaryReader *reader, const
uint8_t *data, size_t file
PyErr_SetString(PyExc_ValueError, "Malformed varint in string
table");
return -1;
}
- if (offset + str_len > file_size) {
+ if (offset > file_size || str_len > file_size - offset) {
PyErr_SetString(PyExc_ValueError, "String table overflow");
return -1;
}
@@ -976,8 +976,8 @@ binary_reader_replay(BinaryReader *reader, PyObject
*collector, PyObject *progre
}
while (offset < reader->sample_data_size) {
- /* Read thread_id (8 bytes) + interpreter_id (4 bytes) */
- if (offset + 13 > reader->sample_data_size) {
+ /* Read thread_id (8 bytes) + interpreter_id (4 bytes) + encoding byte
*/
+ if (reader->sample_data_size - offset < SAMPLE_HEADER_FIXED_SIZE) {
break; /* End of data */
}
diff --git a/Modules/_remote_debugging/binary_io_writer.c
b/Modules/_remote_debugging/binary_io_writer.c
index c129c93efe23c5..0ac6c88d0373a7 100644
--- a/Modules/_remote_debugging/binary_io_writer.c
+++ b/Modules/_remote_debugging/binary_io_writer.c
@@ -23,7 +23,6 @@
*
============================================================================ */
/* Sample header sizes */
-#define SAMPLE_HEADER_FIXED_SIZE 13 /* thread_id(8) + interpreter_id(4) +
encoding(1) */
#define SAMPLE_HEADER_MAX_SIZE 26 /* fixed + max_varint(10) + status(1)
+ margin */
#define MAX_VARINT_SIZE 10 /* Maximum bytes for a varint64 */
#define MAX_VARINT_SIZE_U32 5 /* Maximum bytes for a varint32 */
@@ -653,10 +652,13 @@ write_sample_with_encoding(BinaryWriter *writer,
ThreadEntry *entry,
memcpy(header_buf, &entry->thread_id, 8);
memcpy(header_buf + 8, &entry->interpreter_id, 4);
header_buf[12] = (uint8_t)encoding_type;
- size_t varint_len = encode_varint_u64(header_buf + 13, timestamp_delta);
- header_buf[13 + varint_len] = status;
+ size_t varint_len = encode_varint_u64(
+ header_buf + SAMPLE_HEADER_FIXED_SIZE,
+ timestamp_delta);
+ header_buf[SAMPLE_HEADER_FIXED_SIZE + varint_len] = status;
- if (writer_write_bytes(writer, header_buf, 14 + varint_len) < 0) {
+ if (writer_write_bytes(writer, header_buf,
+ SAMPLE_HEADER_FIXED_SIZE + varint_len + 1) < 0) {
return -1;
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]