mirror of
https://github.com/transmission/transmission.git
synced 2025-12-20 02:18:42 +00:00
fix: 5422 use-after-free in peerMsgs::canRead (#5425)
This commit is contained in:
@@ -1731,15 +1731,15 @@ ReadState canRead(tr_peerIo* io, void* vmsgs, size_t* piece)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// read <payload>
|
// read <payload>
|
||||||
auto& payload = msgs->incoming.payload;
|
auto& current_payload = msgs->incoming.payload;
|
||||||
auto const full_payload_len = *current_message_len - sizeof(uint8_t /*message_type*/);
|
auto const full_payload_len = *current_message_len - sizeof(uint8_t /*message_type*/);
|
||||||
auto n_left = full_payload_len - std::size(payload);
|
auto n_left = full_payload_len - std::size(current_payload);
|
||||||
while (n_left > 0U && io->read_buffer_size() > 0U)
|
while (n_left > 0U && io->read_buffer_size() > 0U)
|
||||||
{
|
{
|
||||||
auto buf = std::array<char, tr_block_info::BlockSize>{};
|
auto buf = std::array<char, tr_block_info::BlockSize>{};
|
||||||
auto const n_this_pass = std::min({ n_left, io->read_buffer_size(), std::size(buf) });
|
auto const n_this_pass = std::min({ n_left, io->read_buffer_size(), std::size(buf) });
|
||||||
io->read_bytes(std::data(buf), n_this_pass);
|
io->read_bytes(std::data(buf), n_this_pass);
|
||||||
payload.add(std::data(buf), n_this_pass);
|
current_payload.add(std::data(buf), n_this_pass);
|
||||||
n_left -= n_this_pass;
|
n_left -= n_this_pass;
|
||||||
logtrace(msgs, fmt::format("read {:d} payload bytes; {:d} left to go", n_this_pass, n_left));
|
logtrace(msgs, fmt::format("read {:d} payload bytes; {:d} left to go", n_this_pass, n_left));
|
||||||
}
|
}
|
||||||
@@ -1749,10 +1749,17 @@ ReadState canRead(tr_peerIo* io, void* vmsgs, size_t* piece)
|
|||||||
return READ_LATER;
|
return READ_LATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const [read_state, n_piece_bytes_read] = process_peer_message(msgs, *current_message_type, payload);
|
// The incoming message is now complete. Reset the peerMsgs' incoming
|
||||||
current_message_type.reset();
|
// field so it's ready to receive the next message, then process the
|
||||||
|
// current one with `process_peer_message()`.
|
||||||
|
|
||||||
current_message_len.reset();
|
current_message_len.reset();
|
||||||
payload.clear();
|
auto const message_type = *current_message_type;
|
||||||
|
current_message_type.reset();
|
||||||
|
auto payload = libtransmission::Buffer{};
|
||||||
|
std::swap(payload, current_payload);
|
||||||
|
|
||||||
|
auto const [read_state, n_piece_bytes_read] = process_peer_message(msgs, message_type, payload);
|
||||||
*piece = n_piece_bytes_read;
|
*piece = n_piece_bytes_read;
|
||||||
return read_state;
|
return read_state;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user