[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Security issues in package ekg



On Wed, Mar 21, 2007 at 02:37:42PM +0000, Marcin Owsiany wrote:
> 2661: A memory leak in handling image messages, which may cause memory
> exhaustion resulting in a DoS (ekg program crash). Exploitable by a
> hostile GG user.
> 
> ----------------+-------------------+---------------+-----------------------------
> Dist            | Contains version  | Vulnerable to | Version (to be) fixed in
> ----------------+-------------------+---------------+-----------------------------
> sarge           | 1:1.5+20050411-5  | 2661 only (*) | 1:1.5+20050411-7
> sarge-volatile  | 1:1.5+20050411-6  | 2661 only (*) | 1:1.5+20050411-8

After closer examination it turned out that 1:1.5+20050411-[56] are not
vulnereble to any of the three aforementioned issues.

However, they STILL are vulnerable to CAN-2005-2370 and CAN-2005-2448 which
were missed back in 2005 when preparing DSA-767. I guess it's better to fix
that late rather than never, so I am currently preparing 1:1.5+20050411-7 (for
sarge) and 1:1.5+20050411-8 (for sarge-volatile) to patch them up (see the
interdiff for -7 in attachment, the one for -8 will be almost the same, just
applied to -6 instead of -5).

The version in etch/sid is not vulnerable to these two.

Here is the proposed text for the advisory:


  This advisory includes corrections for two problems in the libgadu3 library and
  the ekg program, which were missing from DSA-767.
  
  Szymon Zygmunt and Michal Bartoszkiewicz discovered a memory alignment
  error in the Gadu library. By sending specially crafted messages, a
  remote attacker could crash the application using the library.
  (CAN-2005-2370)
  
  Marcin Slusarz discovered that the Gadu library did not properly
  handle endianess conversion in some cases. This caused invalid
  behavior on big endian architectures. (CAN-2005-2448)


I guess that these fixes can be issued as an update to DSA-767 and a
debian-volatile announcement, while CVE-2007-166[345] can be covered
just by a DTSA, since the two sets of vulnerabilities are disjoint.

Waiting for an authorization to upload to sarge-security.

Marcin
-- 
Marcin Owsiany <porridge@debian.org>             http://marcin.owsiany.pl/
GnuPG: 1024D/60F41216  FE67 DA2D 0ACA FC5E 3F75  D6F6 3A0D 8AA0 60F4 1216
diff -u ekg-1.5+20050411/debian/changelog ekg-1.5+20050411/debian/changelog
--- ekg-1.5+20050411/debian/changelog	2007-03-25 13:03:36.648014199 +0100
+++ ekg-1.5+20050411/debian/changelog	2007-03-26 18:19:58.626928050 +0100
@@ -1,3 +1,15 @@
+ekg (1:1.5+20050411-7) stable-security; urgency=medium
+
+  * Security upload, fixing two problems missed when preparing DSA-767:
+    - Using revision -7, as -6 was used for a sarge-volatile upload (-7 does
+      not contain any changes from -6)
+  * Fixes a memory alignment error in libgadu, which could lead to a DoS on
+    some architectures (CAN-2005-2370)
+  * Fixes endianness conversion problems, which could cause invalid behavior
+    on big endian machines (CAN-2005-2448)
+
+ -- Marcin Owsiany <porridge@debian.org>  Mon, 26 Mar 2007 18:12:35 +0100
+
 ekg (1:1.5+20050411-5) stable-security; urgency=high
 
   * Security upload
diff -u ekg-1.5+20050411/lib/events.c ekg-1.5+20050411/lib/events.c
--- ekg-1.5+20050411/lib/events.c	2007-03-25 13:03:36.648014199 +0100
+++ ekg-1.5+20050411/lib/events.c	2007-03-26 18:20:22.224402800 +0100
@@ -173,8 +173,7 @@
 	struct gg_msg_image_reply *i = (void*) p;
 	struct gg_image_queue *q, *qq;
 
-	if (!p || !sess || !e)
-	{
+	if (!p || !sess || !e) {
 		errno = EFAULT;
 		return;
 	}
@@ -313,8 +312,11 @@
 					goto fail;
 				}
 			
-				for (i = 0; i < count; i++, p += sizeof(uin_t))
-					e->event.msg.recipients[i] = gg_fix32(*((uint32_t*) p));
+				for (i = 0; i < count; i++, p += sizeof(uint32_t)) {
+					uint32_t u;
+					memcpy(&u, p, sizeof(uint32_t));
+					e->event.msg.recipients[i] = gg_fix32(u);
+				}
 				
 				e->event.msg.recipients_count = count;
 				
@@ -323,7 +325,7 @@
 
 			case 0x02:		/* richtext */
 			{
-				unsigned short len;
+				uint16_t len;
 				char *buf;
 			
 				if (p + 3 > packet_end) {
@@ -331,7 +333,8 @@
 					goto malformed;
 				}
 
-				len = gg_fix16(*((unsigned short*) (p + 1)));
+				memcpy(&len, p + 1, sizeof(uint16_t));
+				len = gg_fix16(len);
 
 				if (!(buf = malloc(len))) {
 					gg_debug(GG_DEBUG_MISC, "// gg_handle_recv_msg() not enough memory for richtext data\n");
@@ -395,6 +398,8 @@
 					goto malformed;
 				}
 
+				rep->size = gg_fix32(rep->size);
+				rep->crc32 = gg_fix32(rep->crc32);
 				gg_image_queue_parse(e, p, (unsigned int)(packet_end - p), sess, gg_fix32(r->sender));
 
 				return 0;
@@ -483,7 +488,7 @@
 				goto fail;
 			}
 
-			if (gg_fix32(n->status) == GG_STATUS_BUSY_DESCR || gg_fix32(n->status == GG_STATUS_NOT_AVAIL_DESCR) || gg_fix32(n->status) == GG_STATUS_AVAIL_DESCR) {
+			if (gg_fix32(n->status) == GG_STATUS_BUSY_DESCR || gg_fix32(n->status) == GG_STATUS_NOT_AVAIL_DESCR || gg_fix32(n->status) == GG_STATUS_AVAIL_DESCR) {
 				e->type = GG_EVENT_NOTIFY_DESCR;
 				
 				if (!(e->event.notify_descr.notify = (void*) malloc(sizeof(*n) * 2))) {
@@ -520,7 +525,7 @@
 				for (i = 0; i < count; i++) {
 					e->event.notify[i].uin = gg_fix32(e->event.notify[i].uin);
 					e->event.notify[i].status = gg_fix32(e->event.notify[i].status);
-					e->event.notify[i].remote_port = gg_fix16(e->event.notify[i].remote_port);		
+					e->event.notify[i].remote_port = gg_fix16(e->event.notify[i].remote_port);
 				}
 			}
 
@@ -654,8 +659,11 @@
 
 				e->event.status60.descr = buf;
 
-				if (len > 4 && p[h->length - 5] == 0)
-					e->event.status60.time = *((int*) (p + h->length - 4));
+				if (len > 4 && p[h->length - 5] == 0) {
+					uint32_t t;
+					memcpy(&t, p + h->length - 4, sizeof(uint32_t));
+					e->event.status60.time = gg_fix32(t);
+				}
 			}
 
 			break;
@@ -1073,7 +1081,7 @@
 
 			if ((tmp = strchr(host, ':'))) {
 				*tmp = 0;
-				port = atoi(tmp+1);
+				port = atoi(tmp + 1);
 			}
 
 			addr.s_addr = inet_addr(host);
@@ -1411,7 +1419,7 @@
 			
 			if (sess->external_addr && sess->external_port > 1023) {
 				l.external_ip = sess->external_addr;
-				l.external_port = sess->external_port;
+				l.external_port = gg_fix16(sess->external_port);
 			}
 
 			gg_debug(GG_DEBUG_TRAFFIC, "// gg_watch_fd() sending GG_LOGIN60 packet\n");
only in patch2:
unchanged:
--- ekg-1.5+20050411.orig/src/commands.c	2005-03-17 17:30:29.000000000 +0000
+++ ekg-1.5+20050411/src/commands.c	2007-03-26 18:20:22.228403050 +0100
@@ -3486,6 +3486,7 @@
 
 	tmp = gg_crc32(0, image, size);
 	gg_debug(GG_DEBUG_MISC, "// crc32 = 0x%.8x, size = %d\n", tmp, size);
+	tmp = gg_fix32(tmp);
 	memcpy(format + 12, &tmp, 4);
 	tmp = gg_fix32(size);
 	memcpy(format + 8, &tmp, 4);
only in patch2:
unchanged:
--- ekg-1.5+20050411.orig/src/events.c	2005-04-09 22:08:36.000000000 +0100
+++ ekg-1.5+20050411/src/events.c	2007-03-26 18:20:22.228403050 +0100
@@ -498,7 +498,7 @@
 			if ((font & GG_FONT_IMAGE)) {
 				struct gg_msg_richtext_image *m = (void*) &p[i];
 
-				gg_debug(GG_DEBUG_MISC, "// ekg: inline image: sender=%d, size=%d, crc32=%.8x\n", e->event.msg.sender, m->size, m->crc32);
+				gg_debug(GG_DEBUG_MISC, "// ekg: inline image: sender=%d, size=%d, crc32=%.8x\n", e->event.msg.sender, gg_fix32(m->size), gg_fix32(m->crc32));
 
 				imageno++;
 

Attachment: signature.asc
Description: Digital signature


Reply to: