summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorHeikki Linnakangas2025-04-02 13:41:48 +0000
committerHeikki Linnakangas2025-04-02 13:41:48 +0000
commita460251f0a1ac987f0225203ff9593704da0b1a9 (patch)
tree009893fb5dc0e934b15abf6eabfe20fda63b3d4d /src/include
parent285613c60a7aff5daaf281c67002483b0d26e715 (diff)
Make cancel request keys longer
Currently, the 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. Hence make the key longer, to make it harder to guess. The longer cancellation keys are generated when using the new protocol version 3.2. For connections using version 3.0, short 4-bytes keys are still used. The new longer key length is not hardcoded in the protocol anymore, the client is expected to deal with variable length keys, up to 256 bytes. This flexibility allows e.g. a connection pooler to add more information to the cancel key, which might be useful for finding the connection. Reviewed-by: Jelte Fennema-Nio <postgres@jeltef.nl> Reviewed-by: Robert Haas <robertmhaas@gmail.com> (earlier versions) Discussion: https://www.postgresql.org/message-id/508d0505-8b7a-4864-a681-e7e5edfe32aa@iki.fi
Diffstat (limited to 'src/include')
-rw-r--r--src/include/libpq/pqcomm.h8
-rw-r--r--src/include/miscadmin.h4
-rw-r--r--src/include/storage/procsignal.h14
3 files changed, 21 insertions, 5 deletions
diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
index 0aceb7147c7..d11069cf8dc 100644
--- a/src/include/libpq/pqcomm.h
+++ b/src/include/libpq/pqcomm.h
@@ -128,7 +128,12 @@ typedef uint32 AuthRequest;
*
* The cancel request code must not match any protocol version number
* we're ever likely to use. This random choice should do.
+ *
+ * Before PostgreSQL v18 and the protocol version bump from 3.0 to 3.2, the
+ * cancel key was always 4 bytes. With protocol version 3.2, it's variable
+ * length.
*/
+
#define CANCEL_REQUEST_CODE PG_PROTOCOL(1234,5678)
typedef struct CancelRequestPacket
@@ -136,7 +141,8 @@ typedef struct CancelRequestPacket
/* Note that each field is stored in network byte order! */
MsgType cancelRequestCode; /* code to identify a cancel request */
uint32 backendPID; /* PID of client's backend */
- uint32 cancelAuthCode; /* secret key to authorize cancel */
+ char cancelAuthCode[FLEXIBLE_ARRAY_MEMBER]; /* secret key to
+ * authorize cancel */
} CancelRequestPacket;
/* Application-Layer Protocol Negotiation is required for direct connections
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 603d0424354..0d8528b2875 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -191,8 +191,8 @@ extern PGDLLIMPORT pg_time_t MyStartTime;
extern PGDLLIMPORT TimestampTz MyStartTimestamp;
extern PGDLLIMPORT struct Port *MyProcPort;
extern PGDLLIMPORT struct Latch *MyLatch;
-extern PGDLLIMPORT bool MyCancelKeyValid;
-extern PGDLLIMPORT int32 MyCancelKey;
+extern PGDLLIMPORT char MyCancelKey[];
+extern PGDLLIMPORT uint8 MyCancelKeyLength;
extern PGDLLIMPORT int MyPMChildSlot;
extern PGDLLIMPORT char OutputFileName[];
diff --git a/src/include/storage/procsignal.h b/src/include/storage/procsignal.h
index 022fd8ed933..016dfd9b3f6 100644
--- a/src/include/storage/procsignal.h
+++ b/src/include/storage/procsignal.h
@@ -57,15 +57,25 @@ typedef enum
} ProcSignalBarrierType;
/*
+ * Length of query cancel keys generated.
+ *
+ * Note that the protocol allows for longer keys, or shorter, but this is the
+ * length we actually generate. Client code, and the server code that handles
+ * incoming cancellation packets from clients, mustn't use this hardcoded
+ * length.
+ */
+#define MAX_CANCEL_KEY_LENGTH 32
+
+/*
* prototypes for functions in procsignal.c
*/
extern Size ProcSignalShmemSize(void);
extern void ProcSignalShmemInit(void);
-extern void ProcSignalInit(bool cancel_key_valid, int32 cancel_key);
+extern void ProcSignalInit(char *cancel_key, int cancel_key_len);
extern int SendProcSignal(pid_t pid, ProcSignalReason reason,
ProcNumber procNumber);
-extern void SendCancelRequest(int backendPID, int32 cancelAuthCode);
+extern void SendCancelRequest(int backendPID, char *cancel_key, int cancel_key_len);
extern uint64 EmitProcSignalBarrier(ProcSignalBarrierType type);
extern void WaitForProcSignalBarrier(uint64 generation);