From: Rajiv Andrade <srajiv@linux.vnet.ibm.com>
Date: Tue, 17 Jan 2012 17:32:42 +0000 (-0200)
Subject: TCSD robustness
X-Git-Url: http://trousers.git.sourceforge.net/git/gitweb.cgi?p=trousers%2Ftrousers;a=commitdiff_plain;h=ae0c2f8c1fd7a96ba0191f83b6057f8cbc51e786;hp=8a06df2ddcbe1ba6802e3da25b9383116b6a9ff5

TCSD robustness

Included a set of boundary checks to increase TCSD robustness.

Signed-off-by: Rajiv Andrade <srajiv@linux.vnet.ibm.com>
---

diff --git a/src/include/rpc_tcstp.h b/src/include/rpc_tcstp.h
index ed79911..50859e2 100644
--- a/src/include/rpc_tcstp.h
+++ b/src/include/rpc_tcstp.h
@@ -31,7 +31,7 @@ struct tcsd_packet_hdr {
 
 struct tcsd_comm_data {
 	BYTE *buf;
-	int buf_size;
+	UINT32 buf_size;
 	struct tcsd_packet_hdr hdr;
 } STRUCTURE_PACKING_ATTRIBUTE;
 
diff --git a/src/include/rpc_tcstp_tcs.h b/src/include/rpc_tcstp_tcs.h
index 9f32814..57eab27 100644
--- a/src/include/rpc_tcstp_tcs.h
+++ b/src/include/rpc_tcstp_tcs.h
@@ -392,8 +392,8 @@ void LoadBlob_LOADKEY_INFO(UINT64 *, BYTE *, TCS_LOADKEY_INFO *);
 void UnloadBlob_LOADKEY_INFO(UINT64 *, BYTE *, TCS_LOADKEY_INFO *);
 void LoadBlob_PCR_EVENT(UINT64 *, BYTE *, TSS_PCR_EVENT *);
 TSS_RESULT UnloadBlob_PCR_EVENT(UINT64 *, BYTE *, TSS_PCR_EVENT *);
-int setData(TCSD_PACKET_TYPE, int, void *, int, struct tcsd_comm_data *);
-UINT32 getData(TCSD_PACKET_TYPE, int, void *, int, struct tcsd_comm_data *);
+int setData(TCSD_PACKET_TYPE, unsigned int, void *, int, struct tcsd_comm_data *);
+UINT32 getData(TCSD_PACKET_TYPE, unsigned int, void *, int, struct tcsd_comm_data *);
 void initData(struct tcsd_comm_data *, int);
 int recv_from_socket(int, void *, int);
 int send_to_socket(int, void *, int);
diff --git a/src/include/tcs_tsp.h b/src/include/tcs_tsp.h
index bba3258..fdca21e 100644
--- a/src/include/tcs_tsp.h
+++ b/src/include/tcs_tsp.h
@@ -90,4 +90,9 @@ struct key_disk_cache
 /* needed by execute transport in the TSP */
 #define TSS_TPM_TXBLOB_HDR_LEN		(sizeof(UINT16) + (2 * sizeof(UINT32)))
 
+#define TSS_TPM_TXBLOB_SIZE		(4096)
+#define TSS_TXBLOB_WRAPPEDCMD_OFFSET	(TSS_TPM_TXBLOB_HDR_LEN + sizeof(UINT32))
+#define TSS_MAX_AUTHS_CAP		(1024)
+#define TSS_REQ_MGR_MAX_RETRIES		(5)
+
 #endif
diff --git a/src/include/tcs_utils.h b/src/include/tcs_utils.h
index 71cf3f7..0f0f4ce 100644
--- a/src/include/tcs_utils.h
+++ b/src/include/tcs_utils.h
@@ -92,11 +92,6 @@ TSS_RESULT owner_evict_init();
 #define EVENT_LOG_final()
 #endif
 
-#define TSS_TPM_TXBLOB_SIZE		(4096)
-#define TSS_TXBLOB_WRAPPEDCMD_OFFSET	(TSS_TPM_TXBLOB_HDR_LEN + sizeof(UINT32))
-#define TSS_MAX_AUTHS_CAP		(1024)
-#define TSS_REQ_MGR_MAX_RETRIES		(5)
-
 #define next( x ) x = x->next
 
 TSS_RESULT key_mgr_dec_ref_count(TCS_KEY_HANDLE);
diff --git a/src/tcs/rpc/tcstp/rpc.c b/src/tcs/rpc/tcstp/rpc.c
index ca1a4df..849f652 100644
--- a/src/tcs/rpc/tcstp/rpc.c
+++ b/src/tcs/rpc/tcstp/rpc.c
@@ -181,7 +181,7 @@ loadData(UINT64 *offset, TCSD_PACKET_TYPE data_type, void *data, int data_size,
 
 int
 setData(TCSD_PACKET_TYPE dataType,
-	int index,
+	unsigned int index,
 	void *theData,
 	int theDataSize,
 	struct tcsd_comm_data *comm)
@@ -194,11 +194,11 @@ setData(TCSD_PACKET_TYPE dataType,
 	offset = 0;
 	if ((result = loadData(&offset, dataType, theData, theDataSize, NULL)) != TSS_SUCCESS)
 		return result;
-	if (((int)comm->hdr.packet_size + (int)offset) < 0) {
+	if ((comm->hdr.packet_size + offset) > TSS_TPM_TXBLOB_SIZE) {
 		LogError("Too much data to be transmitted!");
 		return TCSERR(TSS_E_INTERNAL_ERROR);
 	}
-	if (((int)comm->hdr.packet_size + (int)offset) > comm->buf_size) {
+	if ((comm->hdr.packet_size + offset) > comm->buf_size) {
 		/* reallocate the buffer */
 		BYTE *buffer;
 		int buffer_size = comm->hdr.packet_size + offset;
@@ -229,13 +229,18 @@ setData(TCSD_PACKET_TYPE dataType,
 
 UINT32
 getData(TCSD_PACKET_TYPE dataType,
-	int index,
+	unsigned int index,
 	void *theData,
 	int theDataSize,
 	struct tcsd_comm_data *comm)
 {
 	UINT64 old_offset, offset;
-	TCSD_PACKET_TYPE *type = (TCSD_PACKET_TYPE *)(comm->buf + comm->hdr.type_offset) + index;
+	TCSD_PACKET_TYPE *type;
+
+	if ((comm->hdr.type_offset + index) > comm->buf_size)
+		return TSS_TCP_RPC_BAD_PACKET_TYPE;
+
+	type = (comm->buf + comm->hdr.type_offset) + index;
 
 	if ((UINT32)index >= comm->hdr.num_parms || dataType != *type) {
 		LogDebug("Data type of TCS packet element %d doesn't match.", index);
diff --git a/src/tcs/tcs_pbg.c b/src/tcs/tcs_pbg.c
index 485fc16..39c688c 100644
--- a/src/tcs/tcs_pbg.c
+++ b/src/tcs/tcs_pbg.c
@@ -710,6 +710,9 @@ tpm_rsp_parse(TPM_COMMAND_CODE ordinal, BYTE *b, UINT32 len, ...)
 			return TCSERR(TSS_E_OUTOFMEMORY);
 		}
 
+		if ((offset1 + offset2) > TSS_TPM_TXBLOB_SIZE)
+			return TCSERR(TSS_E_INTERNAL_ERROR);
+
 		memcpy(*data, &b[offset1], offset2);
 		*data_len = offset2;
 		break;
@@ -728,6 +731,9 @@ tpm_rsp_parse(TPM_COMMAND_CODE ordinal, BYTE *b, UINT32 len, ...)
 			return TCSERR(TSS_E_INTERNAL_ERROR);
 		}
 
+		if ((offset2 + TPM_DIGEST_SIZE) > TSS_TPM_TXBLOB_SIZE)
+			return TCSERR(TSS_E_INTERNAL_ERROR);
+
 		if (digest1) {
 			offset1 = offset2 = len - TPM_DIGEST_SIZE;
 			memcpy(digest1, &b[offset2], TPM_DIGEST_SIZE);
@@ -761,6 +767,9 @@ tpm_rsp_parse(TPM_COMMAND_CODE ordinal, BYTE *b, UINT32 len, ...)
 			return TCSERR(TSS_E_INTERNAL_ERROR);
 		}
 
+		if (len > TSS_TPM_TXBLOB_SIZE)
+			return TCSERR(TSS_E_INTERNAL_ERROR);
+
 		offset2 = len - TPM_DIGEST_SIZE;
 		memcpy(digest2, &b[offset2], TPM_DIGEST_SIZE);
 
diff --git a/src/tcs/tcs_utils.c b/src/tcs/tcs_utils.c
index 580f514..7e19d09 100644
--- a/src/tcs/tcs_utils.c
+++ b/src/tcs/tcs_utils.c
@@ -203,7 +203,7 @@ UnloadBlob_BOOL(UINT64 *offset, TSS_BOOL *dataOut, BYTE * blob)
 void
 LoadBlob(UINT64 *offset, UINT32 size, BYTE *container, BYTE *object)
 {
-	if (size == 0)
+	if ((size == 0) || ((*offset + size) > TSS_TPM_TXBLOB_SIZE))
 		return;
 
 	if (container)
@@ -214,7 +214,7 @@ LoadBlob(UINT64 *offset, UINT32 size, BYTE *container, BYTE *object)
 void
 UnloadBlob(UINT64 *offset, UINT32 size, BYTE *container, BYTE *object)
 {
-	if (size == 0)
+	if ((size == 0) || ((*offset + size) > TSS_TPM_TXBLOB_SIZE))
 		return;
 
 	if (object)
diff --git a/src/tcsd/tcsd_threads.c b/src/tcsd/tcsd_threads.c
index 342dfbd..66a1ac7 100644
--- a/src/tcsd/tcsd_threads.c
+++ b/src/tcsd/tcsd_threads.c
@@ -360,7 +360,7 @@ tcsd_thread_run(void *v)
 			break;
 		}
 
-		if (recv_size > data->comm.buf_size ) {
+		if (recv_size > (int) data->comm.buf_size ) {
 			BYTE *new_buffer;
 
 			LogDebug("Increasing communication buffer to %d bytes.", recv_size);
diff --git a/src/tspi/rpc/tcstp/rpc.c b/src/tspi/rpc/tcstp/rpc.c
index 963da1f..da710f8 100644
--- a/src/tspi/rpc/tcstp/rpc.c
+++ b/src/tspi/rpc/tcstp/rpc.c
@@ -123,11 +123,11 @@ setData(TCSD_PACKET_TYPE dataType,
         offset = 0;
         if ((result = loadData(&offset, dataType, theData, theDataSize, NULL)))
                 return result;
-        if (((int)comm->hdr.packet_size + (int)offset) < 0) {
+        if ((comm->hdr.packet_size + offset) > TSS_TPM_TXBLOB_SIZE) {
                 LogError("Too much data to be transmitted!");
                 return TSPERR(TSS_E_INTERNAL_ERROR);
         }
-        if (((int)comm->hdr.packet_size + (int)offset) > comm->buf_size) {
+        if ((comm->hdr.packet_size + offset) > comm->buf_size) {
                 /* reallocate the buffer */
                 BYTE *buffer;
                 int buffer_size = comm->hdr.packet_size + offset;
@@ -389,7 +389,7 @@ send_init(struct host_table_entry *hte)
 
 	buffer = hte->comm.buf;
 	recv_size = sizeof(struct tcsd_packet_hdr);
-	if ((recv_size = recv_from_socket(sd, buffer, recv_size)) < 0) {
+	if (recv_from_socket(sd, buffer, recv_size) < 0) {
 		result = TSPERR(TSS_E_COMM_FAILURE);
 		goto err_exit;
 	}
@@ -404,7 +404,7 @@ send_init(struct host_table_entry *hte)
 		goto err_exit;
 	}
 
-	if (recv_size > hte->comm.buf_size ) {
+	if (recv_size > (int) hte->comm.buf_size ) {
 		BYTE *new_buffer;
 
 		LogDebug("Increasing communication buffer to %d bytes.", recv_size);
@@ -421,7 +421,7 @@ send_init(struct host_table_entry *hte)
 
 	/* get the rest of the packet */
 	recv_size -= sizeof(struct tcsd_packet_hdr);    /* already received the header */
-	if ((recv_size = recv_from_socket(sd, buffer, recv_size)) < 0) {
+	if (recv_from_socket(sd, buffer, recv_size) < 0) {
 		result = TSPERR(TSS_E_COMM_FAILURE);
 		goto err_exit;
 	}
@@ -464,7 +464,7 @@ tcs_sendit(struct host_table_entry *hte)
 		goto err_exit;
 	}
 
-	if (recv_size > hte->comm.buf_size ) {
+	if (recv_size > (int) hte->comm.buf_size ) {
 		BYTE *new_buffer;
 
 		LogDebug("Increasing communication buffer to %d bytes.", recv_size);
