diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml index e63647c093b..b5395604fb8 100644 --- a/doc/src/sgml/protocol.sgml +++ b/doc/src/sgml/protocol.sgml @@ -4136,7 +4136,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" message, indicated by the length field. - The maximum key length is 256 bytes. The + The minimum and maximum key length are 4 and 256 bytes, respectively. The PostgreSQL server only sends keys up to 32 bytes, but the larger maximum size allows for future server versions, as well as connection poolers and other middleware, to use diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c index 0cca832c06a..8c2d03d8b9f 100644 --- a/src/interfaces/libpq/fe-protocol3.c +++ b/src/interfaces/libpq/fe-protocol3.c @@ -1569,6 +1569,27 @@ getBackendKeyData(PGconn *conn, int msgLength) cancel_key_len = 5 + msgLength - (conn->inCursor - conn->inStart); + if (cancel_key_len != 4 && conn->pversion == PG_PROTOCOL(3, 0)) + { + libpq_append_conn_error(conn, "received invalid BackendKeyData message: cancel key with length %d not allowed in protocol version 3.0 (must be 4 bytes)", cancel_key_len); + handleFatalError(conn); + return 0; + } + + if (cancel_key_len < 4) + { + libpq_append_conn_error(conn, "received invalid BackendKeyData message: cancel key with length %d is too short (minimum 4 bytes)", cancel_key_len); + handleFatalError(conn); + return 0; + } + + if (cancel_key_len > 256) + { + libpq_append_conn_error(conn, "received invalid BackendKeyData message: cancel key with length %d is too long (maximum 256 bytes)", cancel_key_len); + handleFatalError(conn); + return 0; + } + conn->be_cancel_key = malloc(cancel_key_len); if (conn->be_cancel_key == NULL) {