Make query cancellation keys longer
Heikki Linnakangas <hlinnaka@iki.fi>
From: Heikki Linnakangas <hlinnaka@iki.fi>
To: pgsql-hackers <pgsql-hackers@postgresql.org>
Date: 2024-02-29T21:25:43Z
Lists: pgsql-hackers
Attachments
- 0001-Move-cancel-key-generation-to-after-forking-the-back.patch (text/x-patch) patch 0001
- 0002-Make-cancel-request-keys-longer-as-an-optional-proto.patch (text/x-patch) patch 0002
Currently, cancel request key is a 32-bit token, which isn't very much entropy. If you want to cancel another session's query, you can brute-force it. In most environments, an unauthorized cancellation of a query isn't very serious, but it nevertheless would be nice to have more protection from it. The attached patch makes it longer. It is an optional protocol feature, so it's fully backwards-compatible with clients that don't support longer keys. If the client requests the "_pq_.extended_query_cancel" protocol feature, the server will generate a longer 256-bit cancellation key. However, the new longer key length is no longer hardcoded in the protocol. The client is expected to deal with variable length keys, up to some reasonable upper limit (TODO: document the maximum). This flexibility allows e.g. a connection pooler to add more information to the cancel key, which could be useful. If the client doesn't request the protocol feature, the server generates a 32-bit key like before. One complication with this was that because we no longer know how long the key should be, 4-bytes or something longer, until the backend has performed the protocol negotiation, we cannot generate the key in the postmaster before forking the process anymore. The first patch here changes things so that the cancellation key is generated later, in the backend, and the backend advertises the key in the PMSignalState array. This is similar to how this has always worked in EXEC_BACKEND mode with the ShmemBackendArray, but instead of having a separate array, I added fields to the PMSignalState slots. This removes a bunch of EXEC_BACKEND-specific code, which is nice. Any thoughts on this? Documentation is still missing, and there's one TODO on adding a portable time-constant memcmp() function; I'll add those if there's agreement on this otherwise. -- Heikki Linnakangas Neon (https://neon.tech)
Commits
-
Add timingsafe_bcmp(), for constant-time memory comparison
- b282280e9b69 14.23 landed
- 9dcfcb92fff8 15.18 landed
- 1604939b2210 16.14 landed
- 8e34acfda115 17.10 landed
- 09be39112654 18.0 landed
-
Add missing declarations to pg_config.h.in
- b82e7eddb023 18.0 landed
-
docs: Add a new section and a table listing protocol versions
- b05751220b0c 18.0 landed
-
Make cancel request keys longer
- a460251f0a1a 18.0 landed
-
libpq: Add min/max_protocol_version connection options
- 285613c60a7a 18.0 landed
-
libpq: Handle NegotiateProtocolVersion message differently
- 5070349102af 18.0 landed
-
docs: Update phrase on message lengths in the protocol
- 85d799ba8a7f 18.0 landed
-
libpq: Trace all NegotiateProtocolVersion fields
- e87c14b19ed4 18.0 landed
-
libpq: Add PQfullProtocolVersion to exports.txt
- c9d94ea2158b 18.0 landed
-
Move cancel key generation to after forking the backend
- 9d9b9d46f3c5 18.0 landed