summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/storage/ipc/shm_mq.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/backend/storage/ipc/shm_mq.c b/src/backend/storage/ipc/shm_mq.c
index 3721029d254..2ca7e571ff2 100644
--- a/src/backend/storage/ipc/shm_mq.c
+++ b/src/backend/storage/ipc/shm_mq.c
@@ -23,6 +23,7 @@
#include "storage/procsignal.h"
#include "storage/shm_mq.h"
#include "storage/spin.h"
+#include "utils/memutils.h"
/*
* This structure represents the actual queue, stored in shared memory.
@@ -359,6 +360,13 @@ shm_mq_sendv(shm_mq_handle *mqh, shm_mq_iovec *iov, int iovcnt, bool nowait)
for (i = 0; i < iovcnt; ++i)
nbytes += iov[i].len;
+ /* Prevent writing messages overwhelming the receiver. */
+ if (nbytes > MaxAllocSize)
+ ereport(ERROR,
+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+ errmsg("cannot send a message of size %zu via shared memory queue",
+ nbytes)));
+
/* Try to write, or finish writing, the length word into the buffer. */
while (!mqh->mqh_length_word_complete)
{
@@ -652,6 +660,17 @@ shm_mq_receive(shm_mq_handle *mqh, Size *nbytesp, void **datap, bool nowait)
}
nbytes = mqh->mqh_expected_bytes;
+ /*
+ * Should be disallowed on the sending side already, but better check and
+ * error out on the receiver side as well rather than trying to read a
+ * prohibitively large message.
+ */
+ if (nbytes > MaxAllocSize)
+ ereport(ERROR,
+ (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+ errmsg("invalid message size %zu in shared memory queue",
+ nbytes)));
+
if (mqh->mqh_partial_bytes == 0)
{
/*
@@ -680,8 +699,13 @@ shm_mq_receive(shm_mq_handle *mqh, Size *nbytesp, void **datap, bool nowait)
{
Size newbuflen = Max(mqh->mqh_buflen, MQH_INITIAL_BUFSIZE);
+ /*
+ * Double the buffer size until the payload fits, but limit to
+ * MaxAllocSize.
+ */
while (newbuflen < nbytes)
newbuflen *= 2;
+ newbuflen = Min(newbuflen, MaxAllocSize);
if (mqh->mqh_buffer != NULL)
{