Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1f53d0b

Browse files
committed
Avoid invalid alloc size error in shm_mq
In shm_mq_receive(), a huge payload could trigger an unjustified "invalid memory alloc request size" error due to the way the buffer size is increased. Add error checks (documenting the upper limit) and avoid the error by limiting the allocation size to MaxAllocSize. Author: Markus Wanner <markus.wanner@2ndquadrant.com> Discussion: https://www.postgresql.org/message-id/flat/3bb363e7-ac04-0ac4-9fe8-db1148755bfa%402ndquadrant.com
1 parent 0a13777 commit 1f53d0b

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

src/backend/storage/ipc/shm_mq.c

+24
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "storage/procsignal.h"
2525
#include "storage/shm_mq.h"
2626
#include "storage/spin.h"
27+
#include "utils/memutils.h"
2728

2829
/*
2930
* This structure represents the actual queue, stored in shared memory.
@@ -360,6 +361,13 @@ shm_mq_sendv(shm_mq_handle *mqh, shm_mq_iovec *iov, int iovcnt, bool nowait)
360361
for (i = 0; i < iovcnt; ++i)
361362
nbytes += iov[i].len;
362363

364+
/* Prevent writing messages overwhelming the receiver. */
365+
if (nbytes > MaxAllocSize)
366+
ereport(ERROR,
367+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
368+
errmsg("cannot send a message of size %zu via shared memory queue",
369+
nbytes)));
370+
363371
/* Try to write, or finish writing, the length word into the buffer. */
364372
while (!mqh->mqh_length_word_complete)
365373
{
@@ -675,6 +683,17 @@ shm_mq_receive(shm_mq_handle *mqh, Size *nbytesp, void **datap, bool nowait)
675683
}
676684
nbytes = mqh->mqh_expected_bytes;
677685

686+
/*
687+
* Should be disallowed on the sending side already, but better check and
688+
* error out on the receiver side as well rather than trying to read a
689+
* prohibitively large message.
690+
*/
691+
if (nbytes > MaxAllocSize)
692+
ereport(ERROR,
693+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
694+
errmsg("invalid message size %zu in shared memory queue",
695+
nbytes)));
696+
678697
if (mqh->mqh_partial_bytes == 0)
679698
{
680699
/*
@@ -703,8 +722,13 @@ shm_mq_receive(shm_mq_handle *mqh, Size *nbytesp, void **datap, bool nowait)
703722
{
704723
Size newbuflen = Max(mqh->mqh_buflen, MQH_INITIAL_BUFSIZE);
705724

725+
/*
726+
* Double the buffer size until the payload fits, but limit to
727+
* MaxAllocSize.
728+
*/
706729
while (newbuflen < nbytes)
707730
newbuflen *= 2;
731+
newbuflen = Min(newbuflen, MaxAllocSize);
708732

709733
if (mqh->mqh_buffer != NULL)
710734
{

0 commit comments

Comments
 (0)