/pidgin/main: 89b326ceca25: Merged TALOS-CAN-0136

Gary Kramlich grim at reaperworld.com
Mon Jun 20 20:09:59 EDT 2016


Changeset: 89b326ceca25c5251e002b1423add4f63bc3c3e1
Author:	 Gary Kramlich <grim at reaperworld.com>
Date:	 2016-06-12 22:15 -0500
Branch:	 release-2.x.y
URL: https://hg.pidgin.im/pidgin/main/rev/89b326ceca25

Description:

Merged TALOS-CAN-0136

diffstat:

 ChangeLog                           |    2 +
 libpurple/protocols/mxit/http.c     |   17 ++--
 libpurple/protocols/mxit/http.h     |    4 +-
 libpurple/protocols/mxit/protocol.c |  125 +++++++++++++++++++++--------------
 4 files changed, 90 insertions(+), 58 deletions(-)

diffs (truncated from 479 to 300 lines):

diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -33,6 +33,8 @@ version 2.10.13 (MM/DD/YY):
 	  (TALOS-CAN-0133)
 	* Fixed a remote denial of service that could result in an out-of-bounds
 	  read.  Discovered by Yves Younan of Cisco Talos (TALOS-CAN-0134)
+	* Fixed multiple remote buffer overflows.  Discovered by Yves Younan of
+	  Cisco Talos.  (TALOS-CAN-0136)
 
 version 2.10.12 (12/31/15):
 	General:
diff --git a/libpurple/protocols/mxit/http.c b/libpurple/protocols/mxit/http.c
--- a/libpurple/protocols/mxit/http.c
+++ b/libpurple/protocols/mxit/http.c
@@ -63,9 +63,9 @@ static void free_http_request( struct ht
  *  @param pktlen		The length of the packet data
  *  @return				Return -1 on error, otherwise 0
  */
-static int mxit_http_raw_write( int fd, const char* pktdata, int pktlen )
+static int mxit_http_raw_write( int fd, const char* pktdata, size_t pktlen )
 {
-	int		written;
+	size_t	written;
 	int		res;
 
 	written = 0;
@@ -315,22 +315,25 @@ static void mxit_cb_http_connect( gpoint
  *	@param session		The MXit session object
  *	@param host			The server name to connect to
  *	@param port			The port number to connect to
- *	@param data			The HTTP request data (including HTTP headers etc.)
+ *	@param header		The HTTP header.
+ *	@param data			The HTTP request data.
  *	@param datalen		The HTTP request data length
  */
-void mxit_http_send_request( struct MXitSession* session, char* host, int port, const char* data, int datalen )
+void mxit_http_send_request( struct MXitSession* session, char* host, int port, gchar* header, const char* data, size_t datalen )
 {
 	PurpleProxyConnectData*		con	= NULL;
 	struct http_request*		req;
+	size_t						headerlen = strlen( header );
 
 	/* build the http request */
 	req = g_new0( struct http_request, 1 );
 	req->session = session;
 	req->host = host;
 	req->port = port;
-	req->data = g_malloc0( datalen );
-	memcpy( req->data, data, datalen );
-	req->datalen = datalen;
+	req->data = g_malloc0( headerlen + datalen );
+	memcpy( req->data, header, headerlen );
+	memcpy( req->data + headerlen, data, datalen );
+	req->datalen = headerlen + datalen;
 
 	/* open connection to the HTTP server */
 	con = purple_proxy_connect( NULL, session->acc, host, port, mxit_cb_http_connect, req );
diff --git a/libpurple/protocols/mxit/http.h b/libpurple/protocols/mxit/http.h
--- a/libpurple/protocols/mxit/http.h
+++ b/libpurple/protocols/mxit/http.h
@@ -35,11 +35,11 @@ struct http_request
 	char*					host;
 	int						port;
 	char*					data;
-	int						datalen;
+	size_t					datalen;
 };
 
 
-void mxit_http_send_request( struct MXitSession* session, char* host, int port, const char* data, int datalen );
+void mxit_http_send_request( struct MXitSession* session, char* host, int port, gchar* header, const char* data, size_t datalen );
 
 
 
diff --git a/libpurple/protocols/mxit/protocol.c b/libpurple/protocols/mxit/protocol.c
--- a/libpurple/protocols/mxit/protocol.c
+++ b/libpurple/protocols/mxit/protocol.c
@@ -148,6 +148,34 @@ gboolean find_active_chat( const GList* 
 }
 
 
+/*------------------------------------------------------------------------
+ * scnprintf
+ *
+ *	@param string		The destination buffer.
+ *	@param size			The maximum size of the destination buffer.
+ * 	@param format		The format string
+ *	@param ...			The parameters to the format string.
+ *	@return				The number of characters actually stored in the buffer.
+ */
+static int scnprintf( gchar* string, size_t size, const char *format, ... )
+{
+	va_list args;
+	guint i;
+
+	va_start( args, format );
+	i = g_vsnprintf( string, size, format, args );
+	va_end( args );
+
+	if ( i < size )
+		return i;
+	else if ( size > 0 )		/* destination buffer too short - return number of characters actually inserted */
+		return size - 1;
+	else
+		return 0;
+}
+
+
+
 /*========================================================================================================================
  * Low-level Packet transmission
  */
@@ -334,11 +362,10 @@ static void mxit_write_http_get( struct 
  */
 static void mxit_write_http_post( struct MXitSession* session, struct tx_packet* packet )
 {
-	char		request[256 + packet->datalen];
-	int			reqlen;
 	char*		host_name;
 	int			host_port;
 	gboolean	ok;
+	gchar*		httpheader;
 
 	/* extract the HTTP host name and host port number to connect to */
 	ok = purple_url_parse( session->http_server, &host_name, &host_port, NULL, NULL, NULL );
@@ -350,8 +377,8 @@ static void mxit_write_http_post( struct
 	packet->header[packet->headerlen - 1] = '\0';
 	packet->headerlen--;
 
-	/* build the HTTP request packet */
-	reqlen = g_snprintf( request, 256,
+	/* build the HTTP request header */
+	httpheader = g_strdup_printf(
 					"POST %s?%s HTTP/1.1\r\n"
 					"User-Agent: " MXIT_HTTP_USERAGENT "\r\n"
 					"Content-Type: application/octet-stream\r\n"
@@ -364,17 +391,17 @@ static void mxit_write_http_post( struct
 					packet->datalen - MXIT_MS_OFFSET
 	);
 
-	/* copy over the packet body data (could be binary) */
-	memcpy( request + reqlen, packet->data + MXIT_MS_OFFSET, packet->datalen - MXIT_MS_OFFSET );
-	reqlen += packet->datalen;
-
 #ifdef	DEBUG_PROTOCOL
 	purple_debug_info( MXIT_PLUGIN_ID, "HTTP POST:\n" );
-	dump_bytes( session, request, reqlen );
+	dump_bytes( session, httpheader, strlen( httpheader ) );
+	dump_bytes( session, packet->data + MXIT_MS_OFFSET, packet->datalen - MXIT_MS_OFFSET );
 #endif
 
 	/* send the request to the HTTP server */
-	mxit_http_send_request( session, host_name, host_port, request, reqlen );
+	mxit_http_send_request( session, host_name, host_port, httpheader, packet->data + MXIT_MS_OFFSET, packet->datalen - MXIT_MS_OFFSET );
+
+	/* cleanup */
+	g_free( httpheader );
 }
 
 
@@ -463,23 +490,23 @@ static void mxit_queue_packet( struct MX
 	packet->headerlen = 0;
 
 	/* create generic packet header */
-	hlen = g_snprintf( header, sizeof( header ), "id=%s%c", purple_account_get_username( session->acc ), CP_REC_TERM );	/* client mxitid */
+	hlen = scnprintf( header, sizeof( header ), "id=%s%c", purple_account_get_username( session->acc ), CP_REC_TERM );	/* client mxitid */
 
 	if ( session->http ) {
 		/* http connection only */
-		hlen += g_snprintf( header + hlen, sizeof( header ) - hlen, "s=" );
+		hlen += scnprintf( header + hlen, sizeof( header ) - hlen, "s=" );
 		if ( session->http_sesid > 0 ) {
-			hlen += g_snprintf( header + hlen, sizeof( header ) - hlen, "%u%c", session->http_sesid, CP_FLD_TERM );	/* http session id */
+			hlen += scnprintf( header + hlen, sizeof( header ) - hlen, "%u%c", session->http_sesid, CP_FLD_TERM );	/* http session id */
 		}
 		session->http_seqno++;
-		hlen += g_snprintf( header + hlen, sizeof( header ) - hlen, "%u%c", session->http_seqno, CP_REC_TERM );		/* http request sequence id */
+		hlen += scnprintf( header + hlen, sizeof( header ) - hlen, "%u%c", session->http_seqno, CP_REC_TERM );		/* http request sequence id */
 	}
 
-	hlen += g_snprintf( header + hlen, sizeof( header ) - hlen, "cm=%i%c", cmd, CP_REC_TERM ); 						/* packet command */
+	hlen += scnprintf( header + hlen, sizeof( header ) - hlen, "cm=%i%c", cmd, CP_REC_TERM ); 						/* packet command */
 
 	if ( !session->http ) {
 		/* socket connection only */
-		packet->headerlen = g_snprintf( packet->header, sizeof( packet->header ), "ln=%i%c", ( datalen + hlen ), CP_REC_TERM );		/* packet length */
+		packet->headerlen = scnprintf( packet->header, sizeof( packet->header ), "ln=%i%c", ( datalen + hlen ), CP_REC_TERM );		/* packet length */
 	}
 
 	/* copy the header to packet */
@@ -710,7 +737,7 @@ void mxit_send_register( struct MXitSess
 	clientVersion = g_strdup_printf( "%c-%i.%i.%i-%s-%s", MXIT_CP_DISTCODE, PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION, PURPLE_MICRO_VERSION, MXIT_CP_ARCH, MXIT_CP_PLATFORM );
 
 	/* convert the packet to a byte stream */
-	datalen = g_snprintf( data, sizeof( data ),
+	datalen = scnprintf( data, sizeof( data ),
 								"ms=%s%c%s%c%i%c%s%c"		/* "ms"=password\1version\1maxreplyLen\1name\1 */
 								"%s%c%i%c%s%c%s%c"			/* dateOfBirth\1gender\1location\1capabilities\1 */
 								"%s%c%i%c%s%c%s"			/* dc\1features\1dialingcode\1locale */
@@ -748,7 +775,7 @@ void mxit_send_login( struct MXitSession
 	clientVersion = g_strdup_printf( "%c-%i.%i.%i-%s-%s", MXIT_CP_DISTCODE, PURPLE_MAJOR_VERSION, PURPLE_MINOR_VERSION, PURPLE_MICRO_VERSION, MXIT_CP_ARCH, MXIT_CP_PLATFORM );
 
 	/* convert the packet to a byte stream */
-	datalen = g_snprintf( data, sizeof( data ),
+	datalen = scnprintf( data, sizeof( data ),
 								"ms=%s%c%s%c%i%c"			/* "ms"=password\1version\1getContacts\1 */
 								"%s%c%s%c%i%c"				/* capabilities\1dc\1features\1 */
 								"%s%c%s%c"					/* dialingcode\1locale\1 */
@@ -762,7 +789,7 @@ void mxit_send_login( struct MXitSession
 	/* include "custom resource" information */
 	splashId = splash_current( session );
 	if ( splashId != NULL )
-		datalen += g_snprintf( data + datalen, sizeof( data ) - datalen, "%ccr=%s", CP_REC_TERM, splashId );
+		datalen += scnprintf( data + datalen, sizeof( data ) - datalen, "%ccr=%s", CP_REC_TERM, splashId );
 
 	/* queue packet for transmission */
 	mxit_queue_packet( session, data, datalen, CP_CMD_LOGIN );
@@ -792,7 +819,7 @@ void mxit_send_message( struct MXitSessi
 		markuped_msg = g_strdup( msg );
 
 	/* convert the packet to a byte stream */
-	datalen = g_snprintf( data, sizeof( data ),
+	datalen = scnprintf( data, sizeof( data ),
 								"ms=%s%c%s%c%i%c%i",		/* "ms"=jid\1msg\1type\1flags */
 								to, CP_FLD_TERM, markuped_msg, CP_FLD_TERM, msgtype, CP_FLD_TERM, CP_MSG_MARKUP | CP_MSG_EMOTICON
 	);
@@ -819,14 +846,14 @@ void mxit_send_extprofile_request( struc
 	int				datalen;
 	unsigned int	i;
 
-	datalen = g_snprintf( data, sizeof( data ),
+	datalen = scnprintf( data, sizeof( data ),
 								"ms=%s%c%i",		/* "ms="mxitid\1nr_attributes */
 								( username ? username : "" ), CP_FLD_TERM, nr_attrib
 	);
 
 	/* add attributes */
 	for ( i = 0; i < nr_attrib; i++ )
-		datalen += g_snprintf( data + datalen, sizeof( data ) - datalen, "%c%s", CP_FLD_TERM, attribute[i] );
+		datalen += scnprintf( data + datalen, sizeof( data ) - datalen, "%c%s", CP_FLD_TERM, attribute[i] );
 
 	/* queue packet for transmission */
 	mxit_queue_packet( session, data, datalen, CP_CMD_EXTPROFILE_GET );
@@ -852,7 +879,7 @@ void mxit_send_extprofile_update( struct
 		parts = g_strsplit( attributes, "\01", 1 + ( nr_attrib * 3 ) );
 
 	/* convert the packet to a byte stream */
-	datalen = g_snprintf( data, sizeof( data ),
+	datalen = scnprintf( data, sizeof( data ),
 								"ms=%s%c%i",	/* "ms"=password\1nr_attibutes  */
 								( password ) ? password : "", CP_FLD_TERM, nr_attrib
 	);
@@ -864,7 +891,7 @@ void mxit_send_extprofile_update( struct
 			g_strfreev( parts );
 			return;
 		}
-		datalen += g_snprintf( data + datalen, sizeof( data ) - datalen,
+		datalen += scnprintf( data + datalen, sizeof( data ) - datalen,
 								"%c%s%c%s%c%s",		/* \1name\1type\1value  */
 								CP_FLD_TERM, parts[i], CP_FLD_TERM, parts[i + 1], CP_FLD_TERM, parts[i + 2] );
 	}
@@ -892,13 +919,13 @@ void mxit_send_suggest_friends( struct M
 	unsigned int	i;
 
 	/* convert the packet to a byte stream */
-	datalen = g_snprintf( data, sizeof( data ),
+	datalen = scnprintf( data, sizeof( data ),
 								"ms=%i%c%s%c%i%c%i%c%i",	/* inputType \1 input \1 maxSuggestions \1 startIndex \1 numAttributes \1 name0 \1 name1 ... \1 nameN */
 								CP_SUGGEST_FRIENDS, CP_FLD_TERM, "", CP_FLD_TERM, max, CP_FLD_TERM, 0, CP_FLD_TERM, nr_attrib );
 
 	/* add attributes */
 	for ( i = 0; i < nr_attrib; i++ )
-		datalen += g_snprintf( data + datalen, sizeof( data ) - datalen, "%c%s", CP_FLD_TERM, attribute[i] );
+		datalen += scnprintf( data + datalen, sizeof( data ) - datalen, "%c%s", CP_FLD_TERM, attribute[i] );
 
 	/* queue packet for transmission */
 	mxit_queue_packet( session, data, datalen, CP_CMD_SUGGESTCONTACTS );
@@ -921,13 +948,13 @@ void mxit_send_suggest_search( struct MX
 	unsigned int	i;
 
 	/* convert the packet to a byte stream */
-	datalen = g_snprintf( data, sizeof( data ),
+	datalen = scnprintf( data, sizeof( data ),
 								"ms=%i%c%s%c%i%c%i%c%i",	/* inputType \1 input \1 maxSuggestions \1 startIndex \1 numAttributes \1 name0 \1 name1 ... \1 nameN */
 								CP_SUGGEST_SEARCH, CP_FLD_TERM, text, CP_FLD_TERM, max, CP_FLD_TERM, 0, CP_FLD_TERM, nr_attrib );
 
 	/* add attributes */
 	for ( i = 0; i < nr_attrib; i++ )
-		datalen += g_snprintf( data + datalen, sizeof( data ) - datalen, "%c%s", CP_FLD_TERM, attribute[i] );
+		datalen += scnprintf( data + datalen, sizeof( data ) - datalen, "%c%s", CP_FLD_TERM, attribute[i] );
 
 	/* queue packet for transmission */
 	mxit_queue_packet( session, data, datalen, CP_CMD_SUGGESTCONTACTS );
@@ -947,14 +974,14 @@ void mxit_send_presence( struct MXitSess
 	int			datalen;
 
 	/* convert the packet to a byte stream */
-	datalen = g_snprintf( data, sizeof( data ),
+	datalen = scnprintf( data, sizeof( data ),



More information about the Commits mailing list