On Thu, Nov 08, 2012 at 08:03:35AM +0100, Moritz Muehlenhoff wrote: > Package: trousers > Severity: grave > Tags: security > Justification: user security hole > > Please see here for details: > https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2012-0698 > > Cheers, > Moritz >
Hi Moritz, I have tested with the python script referenced in the sourceforge ticket [1], and testing/unstable version is not affected. Version in squeeze seems affected, so I have prepared an upload with the fix from upstream [2]. I am attaching the diff to this email, can you confirm me if it is fine, and if I can upload it ? Regards, Pierre [1] http://sourceforge.net/tracker/index.php?func=detail&aid=3473554&group_id=126012&atid=704358 [2] http://trousers.git.sourceforge.net/git/gitweb.cgi?p=trousers/trousers;a=commit;h=ae0c2f8c1fd7a96ba0191f83b6057f8cbc51e786
diff -Nru trousers-0.3.5/debian/changelog trousers-0.3.5/debian/changelog --- trousers-0.3.5/debian/changelog 2010-07-12 10:46:22.000000000 +0200 +++ trousers-0.3.5/debian/changelog 2012-11-08 22:17:25.000000000 +0100 @@ -1,3 +1,10 @@ +trousers (0.3.5-2+squeeze1) stable-security; urgency=high + + * Fix crash when malformed packet is received (CVE-2012-0698) + Closes: #692649 + + -- Pierre Chifflier <pol...@debian.org> Thu, 08 Nov 2012 22:08:58 +0100 + trousers (0.3.5-2) unstable; urgency=low * QA upload. diff -Nru trousers-0.3.5/debian/patches/04-security-cve-2012-0698.patch trousers-0.3.5/debian/patches/04-security-cve-2012-0698.patch --- trousers-0.3.5/debian/patches/04-security-cve-2012-0698.patch 1970-01-01 01:00:00.000000000 +0100 +++ trousers-0.3.5/debian/patches/04-security-cve-2012-0698.patch 2012-11-08 22:17:16.000000000 +0100 @@ -0,0 +1,252 @@ +From ae0c2f8c1fd7a96ba0191f83b6057f8cbc51e786 Mon Sep 17 00:00:00 2001 +From: Rajiv Andrade <sra...@linux.vnet.ibm.com> +Date: Tue, 17 Jan 2012 15:32:42 -0200 +Subject: [PATCH 1/1] TCSD robustness + +Included a set of boundary checks to increase TCSD robustness. + +Signed-off-by: Rajiv Andrade <sra...@linux.vnet.ibm.com> +--- + src/include/rpc_tcstp.h | 2 +- + src/include/rpc_tcstp_tcs.h | 4 ++-- + src/include/tcs_tsp.h | 5 +++++ + src/include/tcs_utils.h | 5 ----- + src/tcs/rpc/tcstp/rpc.c | 15 ++++++++++----- + src/tcs/tcs_pbg.c | 9 +++++++++ + src/tcs/tcs_utils.c | 4 ++-- + src/tcsd/tcsd_threads.c | 2 +- + src/tspi/rpc/tcstp/rpc.c | 12 ++++++------ + 9 files changed, 36 insertions(+), 22 deletions(-) + +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); +-- +1.7.4.1 + diff -Nru trousers-0.3.5/debian/patches/series trousers-0.3.5/debian/patches/series --- trousers-0.3.5/debian/patches/series 2010-05-24 14:11:43.000000000 +0200 +++ trousers-0.3.5/debian/patches/series 2012-11-08 22:17:16.000000000 +0100 @@ -1,3 +1,4 @@ 01-tss-user.patch 02-manapge.patch 03-readme.patch +04-security-cve-2012-0698.patch
signature.asc
Description: Digital signature