1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-07-22 17:18:39 +00:00

Network: Fix serialization version checks (#15477)

This fixes some incorrect assumptions that the read and write version ranges are identical - whereas they're in fact not.
This commit is contained in:
SmallJoker 2024-11-27 18:39:57 +01:00 committed by GitHub
parent 6c324cb871
commit c175046d30
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 46 additions and 49 deletions

View file

@ -63,7 +63,7 @@ void Client::handleCommand_Hello(NetworkPacket* pkt)
if (pkt->getSize() < 1)
return;
u8 serialization_ver;
u8 serialization_ver; // negotiated value
u16 proto_ver;
u16 unused_compression_mode;
u32 auth_mechs;
@ -80,9 +80,9 @@ void Client::handleCommand_Hello(NetworkPacket* pkt)
<< ", proto_ver=" << proto_ver
<< ". Doing auth with mech " << chosen_auth_mechanism << std::endl;
if (!ser_ver_supported(serialization_ver)) {
if (!ser_ver_supported_read(serialization_ver)) {
infostream << "Client: TOCLIENT_HELLO: Server sent "
<< "unsupported ser_fmt_ver"<< std::endl;
<< "unsupported ser_fmt_ver=" << (int)serialization_ver << std::endl;
return;
}

View file

@ -12,6 +12,7 @@
#include "remoteplayer.h"
#include "rollback_interface.h"
#include "scripting_server.h"
#include "serialization.h"
#include "settings.h"
#include "tool.h"
#include "version.h"
@ -83,34 +84,27 @@ void Server::handleCommand_Init(NetworkPacket* pkt)
if (denyIfBanned(peer_id))
return;
// First byte after command is maximum supported
// serialization version
u8 client_max;
u8 max_ser_ver; // SER_FMT_VER_HIGHEST_READ (of client)
u16 unused;
u16 min_net_proto_version = 0;
u16 min_net_proto_version;
u16 max_net_proto_version;
std::string playerName;
*pkt >> client_max >> unused >> min_net_proto_version
>> max_net_proto_version >> playerName;
*pkt >> max_ser_ver >> unused
>> min_net_proto_version >> max_net_proto_version
>> playerName;
u8 our_max = SER_FMT_VER_HIGHEST_READ;
// Use the highest version supported by both
u8 depl_serial_v = std::min(client_max, our_max);
// If it's lower than the lowest supported, give up.
#if SER_FMT_VER_LOWEST_READ > 0
if (depl_serial_v < SER_FMT_VER_LOWEST_READ)
depl_serial_v = SER_FMT_VER_INVALID;
#endif
const u8 serialization_ver = std::min(max_ser_ver, SER_FMT_VER_HIGHEST_WRITE);
if (depl_serial_v == SER_FMT_VER_INVALID) {
if (!ser_ver_supported_write(serialization_ver)) {
actionstream << "Server: A mismatched client tried to connect from " <<
addr_s << " ser_fmt_max=" << (int)client_max << std::endl;
addr_s << " ser_fmt_max=" << (int)serialization_ver << std::endl;
DenyAccess(peer_id, SERVER_ACCESSDENIED_WRONG_VERSION);
return;
}
client->setPendingSerializationVersion(depl_serial_v);
client->setPendingSerializationVersion(serialization_ver);
/*
Read and check network protocol version
@ -263,8 +257,9 @@ void Server::handleCommand_Init(NetworkPacket* pkt)
NetworkPacket resp_pkt(TOCLIENT_HELLO, 0, peer_id);
resp_pkt << depl_serial_v << u16(0) << net_proto_version
<< auth_mechs << std::string_view();
resp_pkt << serialization_ver << u16(0) /* unused */
<< net_proto_version
<< auth_mechs << std::string_view() /* unused */;
Send(&resp_pkt);