From 1144ea3421e4bcc24dd7402a1f21ba94638d591b Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Thu, 24 Jul 2014 09:19:50 -0400
Subject: [PATCH] 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).
---
 src/backend/storage/ipc/shm_mq.c | 7 +++++++
 1 file changed, 7 insertions(+)

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;