|
24 | 24 | #include "storage/procsignal.h"
|
25 | 25 | #include "storage/shm_mq.h"
|
26 | 26 | #include "storage/spin.h"
|
| 27 | +#include "utils/memutils.h" |
27 | 28 |
|
28 | 29 | /*
|
29 | 30 | * This structure represents the actual queue, stored in shared memory.
|
@@ -364,6 +365,13 @@ shm_mq_sendv(shm_mq_handle *mqh, shm_mq_iovec *iov, int iovcnt, bool nowait)
|
364 | 365 | for (i = 0; i < iovcnt; ++i)
|
365 | 366 | nbytes += iov[i].len;
|
366 | 367 |
|
| 368 | + /* Prevent writing messages overwhelming the receiver. */ |
| 369 | + if (nbytes > MaxAllocSize) |
| 370 | + ereport(ERROR, |
| 371 | + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), |
| 372 | + errmsg("cannot send a message of size %zu via shared memory queue", |
| 373 | + nbytes))); |
| 374 | + |
367 | 375 | /* Try to write, or finish writing, the length word into the buffer. */
|
368 | 376 | while (!mqh->mqh_length_word_complete)
|
369 | 377 | {
|
@@ -657,6 +665,17 @@ shm_mq_receive(shm_mq_handle *mqh, Size *nbytesp, void **datap, bool nowait)
|
657 | 665 | }
|
658 | 666 | nbytes = mqh->mqh_expected_bytes;
|
659 | 667 |
|
| 668 | + /* |
| 669 | + * Should be disallowed on the sending side already, but better check and |
| 670 | + * error out on the receiver side as well rather than trying to read a |
| 671 | + * prohibitively large message. |
| 672 | + */ |
| 673 | + if (nbytes > MaxAllocSize) |
| 674 | + ereport(ERROR, |
| 675 | + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), |
| 676 | + errmsg("invalid message size %zu in shared memory queue", |
| 677 | + nbytes))); |
| 678 | + |
660 | 679 | if (mqh->mqh_partial_bytes == 0)
|
661 | 680 | {
|
662 | 681 | /*
|
@@ -685,8 +704,13 @@ shm_mq_receive(shm_mq_handle *mqh, Size *nbytesp, void **datap, bool nowait)
|
685 | 704 | {
|
686 | 705 | Size newbuflen = Max(mqh->mqh_buflen, MQH_INITIAL_BUFSIZE);
|
687 | 706 |
|
| 707 | + /* |
| 708 | + * Double the buffer size until the payload fits, but limit to |
| 709 | + * MaxAllocSize. |
| 710 | + */ |
688 | 711 | while (newbuflen < nbytes)
|
689 | 712 | newbuflen *= 2;
|
| 713 | + newbuflen = Min(newbuflen, MaxAllocSize); |
690 | 714 |
|
691 | 715 | if (mqh->mqh_buffer != NULL)
|
692 | 716 | {
|
|
0 commit comments