Skip to content

Commit 00e2825

Browse files
hlinnakaCommitfest Bot
authored andcommitted
libpq: Be strict about cancel key lengths
The protocol documentation states that the maximum length of a cancel key is 256 bytes. This starts checking for that limit in libpq. Otherwise third party backend implementations will probably start using more bytes anyway. We also start requiring that a protocol 3.0 connection does not send a longer cancel key, to make sure that servers don't start breaking old 3.0-only clients by accident. Finally this also restricts the minimum key length to 4 bytes (both in the protocol spec and in the libpq implementation). Author: Jelte Fennema-Nio <[email protected]> Discussion: https://www.postgresql.org/message-id/[email protected]
1 parent 281757d commit 00e2825

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

doc/src/sgml/protocol.sgml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4136,7 +4136,7 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
41364136
message, indicated by the length field.
41374137
</para>
41384138
<para>
4139-
The maximum key length is 256 bytes. The
4139+
The minimum and maximum key length are 4 and 256 bytes, respectively. The
41404140
<productname>PostgreSQL</productname> server only sends keys up to
41414141
32 bytes, but the larger maximum size allows for future server
41424142
versions, as well as connection poolers and other middleware, to use

src/interfaces/libpq/fe-protocol3.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,6 +1569,27 @@ getBackendKeyData(PGconn *conn, int msgLength)
15691569

15701570
cancel_key_len = 5 + msgLength - (conn->inCursor - conn->inStart);
15711571

1572+
if (cancel_key_len != 4 && conn->pversion == PG_PROTOCOL(3, 0))
1573+
{
1574+
libpq_append_conn_error(conn, "received invalid BackendKeyData message: cancel key length %d is different from 4, which is not supported in version 3.0 of the protocol", cancel_key_len);
1575+
handleFatalError(conn);
1576+
return 0;
1577+
}
1578+
1579+
if (cancel_key_len < 4)
1580+
{
1581+
libpq_append_conn_error(conn, "received invalid BackendKeyData message: cancel key length %d is below minimum of 4 bytes", cancel_key_len);
1582+
handleFatalError(conn);
1583+
return 0;
1584+
}
1585+
1586+
if (cancel_key_len > 256)
1587+
{
1588+
libpq_append_conn_error(conn, "received invalid BackendKeyData message: cancel key length %d exceeds maximum of 256 bytes", cancel_key_len);
1589+
handleFatalError(conn);
1590+
return 0;
1591+
}
1592+
15721593
conn->be_cancel_key = malloc(cancel_key_len);
15731594
if (conn->be_cancel_key == NULL)
15741595
{

0 commit comments

Comments
 (0)