Package: xfstt
Version: 1.2.1-1
Author: Guillem Jover <guillem@hadrons.org>
Status: applied
Description:
 New Maintainer.
 Fixed multiple buffer overflows in the network packet handling:
  CAN-2003-0581.
 Fixed a possible security problem by checking the byteorder magic in
  the connection handshake:
  bugtraq id 8255.

diff -Naur xfstt-1.2/debian/changelog xfstt-1.2.1/debian/changelog
--- xfstt-1.2/debian/changelog	2002-04-15 09:04:43.000000000 +0200
+++ xfstt-1.2.1/debian/changelog	2003-07-31 09:15:54.000000000 +0200
@@ -1,3 +1,14 @@
+xfstt (1.2.1-2) stable-security; urgency=high
+
+  * New Maintainer.
+  * Fixed multiple buffer overflows in the network packet handling:
+    CAN-2003-0581.
+  * Fixed a possible security problem by checking the byteorder magic in
+    the connection handshake:
+    bugtraq id 8255.
+
+ -- Guillem Jover <guillem@debian.org>  Thu, 31 Jul 2003 09:15:49 +0200
+
 xfstt (1.2.1-1) unstable; urgency=low
 
   * See if this closes it finally (Closes: #141452).
diff -Naur xfstt-1.2/debian/control xfstt-1.2.1/debian/control
--- xfstt-1.2/debian/control	2002-04-14 20:28:37.000000000 +0200
+++ xfstt-1.2.1/debian/control	2003-07-31 09:17:50.000000000 +0200
@@ -1,7 +1,7 @@
 Source: xfstt
 Section: x11
 Priority: extra
-Maintainer: Amaya Rodrigo Sastre <amaya@debian.org>
+Maintainer: Guillem Jover <guillem@debian.org>
 Build-Depends: debhelper (>> 3.0.0), xlibs-dev
 Standards-Version: 3.5.6
 
diff -Naur xfstt-1.2/xfstt.cpp xfstt-1.2.1/xfstt.cpp
--- xfstt-1.2/xfstt.cpp	2001-03-23 03:35:27.000000000 +0100
+++ xfstt-1.2.1/xfstt.cpp	2003-07-31 09:19:18.000000000 +0200
@@ -697,6 +697,12 @@
 		return 0;
 
 	dprintf0( "Connecting\n");
+
+	if (req->byteOrder != 'l' && req->byteOrder != 'B') {
+		fputs("xfstt: invalid byteorder, giving up\n", stderr);
+		return 0;
+	}
+
 	dprintf1( "%s endian connection\n",
 		(req->byteOrder == 'l') ? "little" : "big");
 	dprintf2( "version %d.%d\n", req->major_version, req->minor_version);
@@ -819,6 +825,32 @@
 	fe->bmpFormat = hint;
 }
 
+static int
+send_fserror(int sd, int seqno)
+{
+	fsError reply;
+
+	reply.type = FS_Error;
+	reply.request = FSBadLength;
+	reply.sequenceNumber = seqno;
+	reply.length = sizeof(reply) >> 2;
+
+	return write(sd, (void *)&reply, sizeof(reply));
+}
+
+static int
+check_length(int sd, int seqno, fsReq *req, int expected_size)
+{
+	if (req->length < (expected_size >> 2)) {
+		dprintf2("packet size mismatch: %d received bytes, "
+		      "%d expected bytes\n", req->length << 2, expected_size);
+		send_fserror(sd, seqno);
+		return 0;
+	} else {
+		return 1;
+	}
+}
+
 static int working( int sd, Rasterizer* raster, char* replybuf)
 {
 	FontParams fp0 = {{0,0,0,0}, {0,0,0,0}, {VGARES,VGARES}, 0}, fp;
@@ -841,15 +873,12 @@
 		sync();
 #endif
 
-		int length = ((fsReq*)buf)->length << 2;
+		fsReq *fsreq = (fsReq *)buf;
+		int length = fsreq->length << 2;
 		if( length > MAXREQSIZE) {
-			dprintf1( "request too big: %d bytes\n", length);
-			fsError reply;
-			reply.type		= FS_Error;
-			reply.request		= FSBadLength;
-			reply.sequenceNumber	= seqno;
-			reply.length		= sizeof(reply) >> 2;
-			write( sd, (void*)&reply, sizeof(reply));
+			dprintf2("too much data: %d bytes (max=%d)\n",
+			         length, MAXREQSIZE);
+			send_fserror(sd, seqno);
 			break;
 		}
 
@@ -992,7 +1021,13 @@
 		case FS_SetResolution:
 			{
 			fsSetResolutionReq* req = (fsSetResolutionReq*) buf;
-			int numres = req->num_resolutions;	//### 1
+			int numres = req->num_resolutions;
+			int expected_size = numres * sz_fsResolution
+					    + sz_fsSetResolutionReq;
+
+			if (!check_length(sd, seqno, fsreq, expected_size))
+				break;
+
 			dprintf1( "FS_SetResolution * %d\n", numres);
 			fsResolution* res = (fsResolution*)(req + 1);
 			for(; --numres >= 0; ++res) {
@@ -1035,6 +1070,11 @@
 			{
 			fsListFontsReq* req = (fsListFontsReq*) buf;
 			char* pattern = (char*) (req + 1);
+			int expected_size = sz_fsListFontsReq + req->nbytes;
+
+			if (!check_length(sd, seqno, fsreq, expected_size))
+				break;
+
 			pattern[ req->nbytes] = 0;
 			dprintf2( "FS_ListFonts \"%s\" * %ld\n",
 				pattern, req->maxNames);
@@ -1210,15 +1250,6 @@
 			break;
 
 		case FS_QueryXExtents8:
-			// convert to QueryXExtents16 request
-			{
-			fsQueryXExtents8Req* req = (fsQueryXExtents8Req*) buf;
-			U8* p8 = (U8*)(req + 1);
-			U16* p16 = (U16*)p8;
-			for( i = req->num_ranges; --i >= 0;)
-				p16[ i] = htons( p8[ i]);
-			}
-			// fall through
 		case FS_QueryXExtents16:
 			{
 			fsQueryXExtents16Req* req = (fsQueryXExtents16Req*) buf;
@@ -1228,6 +1259,24 @@
 			dprintf2( "range=%d, nranges=%ld\n",
 				req->range, req->num_ranges);
 
+			int item_size = (req->reqType == FS_QueryXExtents8)
+				        ? 1 : 2;
+			int expected_size = sz_fsQueryXExtents8Req
+				            + req->num_ranges * item_size;
+
+			if (!check_length(sd, seqno, fsreq, expected_size))
+				break;
+
+			if (req->reqType == FS_QueryXExtents8) {
+				/*
+				 * Convert to QueryXExtents16 request
+				 */
+				U8 *p8 = (U8 *)(req + 1);
+				U16 *p16 = (U16 *)p8;
+				for (i = req->num_ranges; --i >= 0;)
+					p16[i] = htons(p8[i]);
+			}
+
 			XFSFont* xfs = findFont( req->fid, sd, seqno);
 			if( !xfs)
 				break;
@@ -1296,15 +1345,6 @@
 			break;
 
 		case FS_QueryXBitmaps8:
-			// convert to QueryXBitmaps16 request
-			{
-			fsQueryXBitmaps8Req* req = (fsQueryXBitmaps8Req*) buf;
-			U8* p8 = (U8*)(req + 1);
-			U16* p16 = (U16*)p8;
-			for( i = req->num_ranges; --i >= 0;)
-				p16[ i] = ntohs( p8[ i]);
-			}
-			// fall through
 		case FS_QueryXBitmaps16:
 			{
 			fsQueryXBitmaps16Req* req = (fsQueryXBitmaps16Req*) buf;
@@ -1313,6 +1353,24 @@
 			dprintf2( "range=%d, nranges=%ld\n",
 				req->range, req->num_ranges);
 
+			int item_size = (req->reqType == FS_QueryXExtents8)
+				        ? 1: 2;
+			int expected_size = sz_fsQueryXBitmaps8Req
+					    + req->num_ranges * item_size;
+
+			if (!check_length(sd, seqno, fsreq, expected_size))
+				break;
+
+			if (req->reqType == FS_QueryXBitmaps8) {
+				/*
+				 * Convert to QueryXBitmaps16 request
+				 */
+				U8 *p8 = (U8 *)(req + 1);
+				U16 *p16 = (U16 *)p8;
+				for (i = req->num_ranges; --i >= 0;)
+					p16[i] = ntohs(p8[i]);
+			}
+
 			XFSFont* xfs = findFont( req->fid, sd, seqno);
 			if( !xfs)
 				break;
