From: Robert Haas <rhaas@postgresql.org>
Date: Thu, 24 Jul 2014 13:19:50 +0000 (-0400)
Subject: Prevent shm_mq_send from reading uninitialized memory.
X-Git-Tag: REL9_4_BETA3~138
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=df58a17df29f7ec0ffc8389deee46e81a2a58a60;p=postgresql

Prevent shm_mq_send from reading uninitialized memory.

shm_mq_send_bytes didn't invariably initialize *bytes_written before
returning, which would cause shm_mq_send to read from uninitialized
memory and add the value it found there to mqh->mqh_partial_bytes.
This could cause the next attempt to send a message via the queue to
fail an assertion (if the queue was detached) or copy data from a
garbage pointer value into the queue (if non-blocking mode was in use).
---

diff --git a/src/backend/storage/ipc/shm_mq.c b/src/backend/storage/ipc/shm_mq.c
index 6f9c3a3b6c..d96627a774 100644
--- a/src/backend/storage/ipc/shm_mq.c
+++ b/src/backend/storage/ipc/shm_mq.c
@@ -676,7 +676,10 @@ shm_mq_send_bytes(shm_mq_handle *mqh, Size nbytes, void *data, bool nowait,
 
 		/* Bail out if the queue has been detached. */
 		if (detached)
+		{
+			*bytes_written = sent;
 			return SHM_MQ_DETACHED;
+		}
 
 		if (available == 0)
 		{
@@ -691,12 +694,16 @@ shm_mq_send_bytes(shm_mq_handle *mqh, Size nbytes, void *data, bool nowait,
 				if (nowait)
 				{
 					if (shm_mq_get_receiver(mq) == NULL)
+					{
+						*bytes_written = sent;
 						return SHM_MQ_WOULD_BLOCK;
+					}
 				}
 				else if (!shm_mq_wait_internal(mq, &mq->mq_receiver,
 											   mqh->mqh_handle))
 				{
 					mq->mq_detached = true;
+					*bytes_written = sent;
 					return SHM_MQ_DETACHED;
 				}
 				mqh->mqh_counterparty_attached = true;