Skip to content

Commit 572947c

Browse files
committed
gh-152718: Factor the reader count checks into reader_validate_count
Addresses review feedback: centralize the string/frame/RLE oversized-count validations behind one helper.
1 parent ffe2643 commit 572947c

1 file changed

Lines changed: 27 additions & 21 deletions

File tree

Modules/_remote_debugging/binary_io_reader.c

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -237,15 +237,29 @@ reader_decompress_samples(BinaryReader *reader, const uint8_t *data)
237237
}
238238
#endif
239239

240+
/* Reject a table/run count whose entries cannot fit in the bytes still
241+
* available; a malicious file could otherwise drive a huge allocation.
242+
* Each entry occupies at least min_entry_size bytes. */
243+
static int
244+
reader_validate_count(const char *what, uint32_t count,
245+
size_t available_bytes, size_t min_entry_size)
246+
{
247+
size_t max_possible = available_bytes / min_entry_size;
248+
if (count > max_possible) {
249+
PyErr_Format(PyExc_ValueError,
250+
"Invalid %s count %u exceeds maximum possible %zu",
251+
what, count, max_possible);
252+
return -1;
253+
}
254+
return 0;
255+
}
256+
240257
static inline int
241258
reader_parse_string_table(BinaryReader *reader, const uint8_t *data, size_t file_size)
242259
{
243-
size_t max_strings =
244-
(file_size - reader->string_table_offset) / MIN_STRING_ENTRY_SIZE;
245-
if (reader->strings_count > max_strings) {
246-
PyErr_Format(PyExc_ValueError,
247-
"Invalid string count %u exceeds maximum possible %zu",
248-
reader->strings_count, max_strings);
260+
if (reader_validate_count("string", reader->strings_count,
261+
file_size - reader->string_table_offset,
262+
MIN_STRING_ENTRY_SIZE) < 0) {
249263
return -1;
250264
}
251265

@@ -289,12 +303,9 @@ reader_parse_frame_table(BinaryReader *reader, const uint8_t *data, size_t file_
289303
}
290304
#endif
291305

292-
size_t max_frames =
293-
(file_size - reader->frame_table_offset) / MIN_FRAME_ENTRY_SIZE;
294-
if (reader->frames_count > max_frames) {
295-
PyErr_Format(PyExc_ValueError,
296-
"Invalid frame count %u exceeds maximum possible %zu",
297-
reader->frames_count, max_frames);
306+
if (reader_validate_count("frame", reader->frames_count,
307+
file_size - reader->frame_table_offset,
308+
MIN_FRAME_ENTRY_SIZE) < 0) {
298309
return -1;
299310
}
300311

@@ -1071,15 +1082,10 @@ binary_reader_replay(BinaryReader *reader, PyObject *collector, PyObject *progre
10711082
return -1;
10721083
}
10731084

1074-
/* Validate RLE count to prevent DoS from malicious files.
1075-
* Each RLE sample needs at least 2 bytes (1 byte min varint + 1 status byte).
1076-
* Also reject absurdly large counts that would exhaust memory. */
1077-
size_t remaining_data = reader->sample_data_size - offset;
1078-
size_t max_possible_samples = remaining_data / 2;
1079-
if (count > max_possible_samples) {
1080-
PyErr_Format(PyExc_ValueError,
1081-
"Invalid RLE count %u exceeds maximum possible %zu for remaining data",
1082-
count, max_possible_samples);
1085+
/* Reject a count larger than the remaining bytes can hold; each
1086+
* RLE sample needs at least 2 bytes (1-byte min varint + status). */
1087+
if (reader_validate_count("RLE", count,
1088+
reader->sample_data_size - offset, 2) < 0) {
10831089
return -1;
10841090
}
10851091
if ((uint64_t)count > (uint64_t)PY_SSIZE_T_MAX - (uint64_t)replayed) {

0 commit comments

Comments
 (0)