Skip to content

Commit 609d2c8

Browse files
authored
Fix heap-buffer-overflow in pythonbuf with undersized buffers (#6019)
* Fix heap-buffer-overflow in pythonbuf with undersized buffers (gh-5886) The _sync() UTF-8 remainder logic can leave pptr() past the end of the allocated buffer when buf_size < 4: after moving up to 3 bytes of an incomplete UTF-8 sequence to the front, pbump(remainder) pushes pptr() beyond epptr() and the buffer boundary. The next overflow() then writes out of bounds. Fix by clamping the buffer size to a minimum of 4 in the constructor, ensuring the maximum UTF-8 remainder (3 bytes) plus the overflow slot (1 byte) always fits within the allocated buffer. Made-with: Cursor * Avoid C++14 ODR-use linker error for minimum_buffer_size std::max takes arguments by const&, which ODR-uses the static constexpr member and requires an out-of-line definition in C++14. Replace with a ternary expression that uses the value without taking its address. Made-with: Cursor
1 parent 83f71d8 commit 609d2c8

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

include/pybind11/iostream.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,16 @@ class pythonbuf : public std::streambuf {
117117
int sync() override { return _sync(); }
118118

119119
public:
120+
// Minimum buffer size must accommodate the largest incomplete UTF-8 sequence
121+
// (3 bytes) plus one position reserved for overflow(), i.e. 4 bytes total.
122+
static constexpr size_t minimum_buffer_size = 4;
123+
120124
explicit pythonbuf(const object &pyostream, size_t buffer_size = 1024)
121-
: buf_size(buffer_size), d_buffer(new char[buf_size]), pywrite(pyostream.attr("write")),
125+
: buf_size(buffer_size < minimum_buffer_size // ternary avoids C++14 std::max ODR-use of
126+
// static constexpr
127+
? minimum_buffer_size
128+
: buffer_size),
129+
d_buffer(new char[buf_size]), pywrite(pyostream.attr("write")),
122130
pyflush(pyostream.attr("flush")) {
123131
setp(d_buffer.get(), d_buffer.get() + buf_size - 1);
124132
}

0 commit comments

Comments
 (0)