diff -urBb --exclude-from=../../../samba-cvs/diff.excludes samba-3.0.5-orig/source/libsmb/nmblib.c samba-3.0.5/source/libsmb/nmblib.c
--- samba-3.0.5-orig/source/libsmb/nmblib.c	2004-07-20 11:28:04.000000000 -0500
+++ samba-3.0.5/source/libsmb/nmblib.c	2004-09-09 09:17:47.873805426 -0500
@@ -475,6 +475,11 @@
 	dgram->datasize = length-offset;
 	memcpy(dgram->data,inbuf+offset,dgram->datasize);
 
+	/* Paranioa. Ensure the last 2 bytes in the dgram buffer are
+	   zero. This should be true anyway, just enforce it for paranioa sake. JRA. */
+	SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2));
+	memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2);
+
 	return(True);
 }
 
diff -urBb --exclude-from=../../../samba-cvs/diff.excludes samba-3.0.5-orig/source/nmbd/nmbd_packets.c samba-3.0.5/source/nmbd/nmbd_packets.c
--- samba-3.0.5-orig/source/nmbd/nmbd_packets.c	2004-07-20 11:28:11.000000000 -0500
+++ samba-3.0.5/source/nmbd/nmbd_packets.c	2004-09-09 09:17:47.880803725 -0500
@@ -1203,6 +1203,16 @@
 		return;
 	}
 
+	/* Ensure we have a large enough packet before looking inside. */
+	if (dgram->datasize < (smb_vwv12 - 2)) {
+		/* That's the offset minus the 4 byte length + 2 bytes of offset. */
+		DEBUG(0,("process_dgram: ignoring too short dgram packet (%u) sent to name %s from IP %s\n",
+			(unsigned int)dgram->datasize,
+			nmb_namestr(&dgram->dest_name),
+			inet_ntoa(p->ip) ));
+		return;
+	}
+
 	buf = &dgram->data[0];
 	buf -= 4; /* XXXX for the pseudo tcp length - someday I need to get rid of this */
 
@@ -1212,14 +1222,36 @@
 	len = SVAL(buf,smb_vwv11);
 	buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
 
-	if (len <= 0)
+	if (len <= 0 || len > dgram->datasize) {
+		DEBUG(0,("process_dgram: ignoring malformed1 (datasize = %d, len = %d) datagram \
+packet sent to name %s from IP %s\n",
+			dgram->datasize,
+			len,
+			nmb_namestr(&dgram->dest_name),
+			inet_ntoa(p->ip) ));
 		return;
+	}
 
-	if (buf2 + len > buf + sizeof(dgram->data)) {
-		DEBUG(2,("process_dgram: datagram from %s to %s IP %s for %s len=%d too long.\n",
-			nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
-			inet_ntoa(p->ip), smb_buf(buf),len));
-		len = (buf + sizeof(dgram->data)) - buf;
+	if (buf2 < dgram->data || (buf2 >= dgram->data + dgram->datasize)) {
+		DEBUG(0,("process_dgram: ignoring malformed2 (datasize = %d, len=%d, off=%d) datagram \
+packet sent to name %s from IP %s\n",
+			dgram->datasize,
+			len,
+			PTR_DIFF(buf2, dgram->data),
+			nmb_namestr(&dgram->dest_name),
+			inet_ntoa(p->ip) ));
+		return;
+	}
+
+	if ((buf2 + len < dgram->data) || (buf2 + len > dgram->data + dgram->datasize)) {
+		DEBUG(0,("process_dgram: ignoring malformed3 (datasize = %d, len=%d, off=%d) datagram \
+packet sent to name %s from IP %s\n",
+			dgram->datasize,
+			len,
+			PTR_DIFF(buf2, dgram->data),
+			nmb_namestr(&dgram->dest_name),
+			inet_ntoa(p->ip) ));
+		return;
 	}
 
 	DEBUG(4,("process_dgram: datagram from %s to %s IP %s for %s of type %d len=%d\n",
diff -urBb --exclude-from=../../../samba-cvs/diff.excludes samba-3.0.5-orig/source/nmbd/nmbd_processlogon.c samba-3.0.5/source/nmbd/nmbd_processlogon.c
--- samba-3.0.5-orig/source/nmbd/nmbd_processlogon.c	2004-07-20 11:28:10.000000000 -0500
+++ samba-3.0.5/source/nmbd/nmbd_processlogon.c	2004-09-09 09:17:49.244472259 -0500
@@ -102,8 +102,22 @@
 				char *machine = q;
 				char *user = skip_string(machine,1);
 
+				if (PTR_DIFF(user, buf) >= len) {
+					DEBUG(0,("process_logon_packet: bad packet\n"));
+					return;
+				}
 				getdc = skip_string(user,1);
+
+				if (PTR_DIFF(getdc, buf) >= len) {
+					DEBUG(0,("process_logon_packet: bad packet\n"));
+					return;
+				}
 				q = skip_string(getdc,1);
+
+				if (PTR_DIFF(q + 5, buf) > len) {
+					DEBUG(0,("process_logon_packet: bad packet\n"));
+					return;
+				}
 				token = SVAL(q,3);
 
 				fstrcpy(reply_name,my_name); 
@@ -151,7 +165,17 @@
 				}
 
 				getdc = skip_string(machine,1);
+
+				if (PTR_DIFF(getdc, buf) >= len) {
+					DEBUG(0,("process_logon_packet: bad packet\n"));
+					return;
+				}
 				q = skip_string(getdc,1);
+
+				if (PTR_DIFF(q, buf) >= len) {
+					DEBUG(0,("process_logon_packet: bad packet\n"));
+					return;
+				}
 				q = ALIGN2(q, buf);
 
 				/* At this point we can work out if this is a W9X or NT style
@@ -165,9 +189,19 @@
 				} else {
 					unicomp = q;
 
+					if (PTR_DIFF(q, buf) >= len) {
+						DEBUG(0,("process_logon_packet: bad packet\n"));
+						return;
+					}
+
 					/* A full length (NT style) request */
 					q = skip_unibuf(unicomp, PTR_DIFF(buf + len, unicomp));
 
+					if (PTR_DIFF(q, buf) >= len) {
+						DEBUG(0,("process_logon_packet: bad packet\n"));
+						return;
+					}
+
 					if (len - PTR_DIFF(q, buf) > 8) {
 						/* with NT5 clients we can sometimes
 							get additional data - a length specificed string
@@ -180,6 +214,12 @@
 						}
 						q += 16;
 					}
+
+					if (PTR_DIFF(q + 8, buf) > len) {
+						DEBUG(0,("process_logon_packet: bad packet\n"));
+						return;
+					}
+
 					ntversion = IVAL(q, 0);
 					lmnttoken = SVAL(q, 4);
 					lm20token = SVAL(q, 6);
@@ -240,10 +280,34 @@
 				fstring asccomp;
 
 				q += 2;
+
+				if (PTR_DIFF(q, buf) >= len) {
+					DEBUG(0,("process_logon_packet: bad packet\n"));
+					return;
+				}
+
 				unicomp = q;
 				uniuser = skip_unibuf(unicomp, PTR_DIFF(buf+len, unicomp));
+
+				if (PTR_DIFF(uniuser, buf) >= len) {
+					DEBUG(0,("process_logon_packet: bad packet\n"));
+					return;
+				}
+
 				getdc = skip_unibuf(uniuser,PTR_DIFF(buf+len, uniuser));
+
+				if (PTR_DIFF(getdc, buf) >= len) {
+					DEBUG(0,("process_logon_packet: bad packet\n"));
+					return;
+				}
+
 				q = skip_string(getdc,1);
+
+				if (PTR_DIFF(q + 8, buf) >= len) {
+					DEBUG(0,("process_logon_packet: bad packet\n"));
+					return;
+				}
+
 				q += 4; /* Account Control Bits - indicating username type */
 				domainsidsize = IVAL(q, 0);
 				q += 4;
@@ -270,6 +334,11 @@
 					q += 16;
 				}
 
+				if (PTR_DIFF(q + 8, buf) > len) {
+					DEBUG(0,("process_logon_packet: bad packet\n"));
+					return;
+				}
+
 				ntversion = IVAL(q, 0);
 				lmnttoken = SVAL(q, 4);
 				lm20token = SVAL(q, 6);
@@ -458,6 +527,11 @@
           
 				/* Header */
           
+				if (PTR_DIFF(q + 16, buf) >= len) {
+					DEBUG(0,("process_logon_packet: bad packet\n"));
+					return;
+				}
+
 				low_serial = IVAL(q, 0); q += 4;     /* Low serial number */
 
 				q += 4;                   /* Date/time */
@@ -467,14 +541,42 @@
 				/* Domain info */
           
 				q = skip_string(q, 1);    /* PDC name */
+
+				if (PTR_DIFF(q, buf) >= len) {
+					DEBUG(0,("process_logon_packet: bad packet\n"));
+					return;
+				}
+
 				q = skip_string(q, 1);    /* Domain name */
+
+				if (PTR_DIFF(q, buf) >= len) {
+					DEBUG(0,("process_logon_packet: bad packet\n"));
+					return;
+				}
+
 				q = skip_unibuf(q, PTR_DIFF(buf + len, q)); /* Unicode PDC name */
+
+				if (PTR_DIFF(q, buf) >= len) {
+					DEBUG(0,("process_logon_packet: bad packet\n"));
+					return;
+				}
+
 				q = skip_unibuf(q, PTR_DIFF(buf + len, q)); /* Unicode domain name */
           
 				/* Database info */
           
+				if (PTR_DIFF(q + 2, buf) >= len) {
+					DEBUG(0,("process_logon_packet: bad packet\n"));
+					return;
+				}
+
 				db_count = SVAL(q, 0); q += 2;
           
+				if (PTR_DIFF(q + (db_count*20), buf) >= len) {
+					DEBUG(0,("process_logon_packet: bad packet\n"));
+					return;
+				}
+
 				db_info = (struct sam_database_info *)
 						malloc(sizeof(struct sam_database_info) * db_count);
 
diff -urBb --exclude-from=../../../samba-cvs/diff.excludes samba-3.0.5-orig/source/libsmb/asn1.c samba-3.0.5/source/libsmb/asn1.c
--- samba-3.0.5-orig/source/libsmb/asn1.c	2004-07-20 11:28:04.000000000 -0500
+++ samba-3.0.5/source/libsmb/asn1.c	2004-09-09 09:41:23.170796486 -0500
@@ -219,6 +219,9 @@
 /* read from a ASN1 buffer, advancing the buffer pointer */
 BOOL asn1_read(ASN1_DATA *data, void *p, int len)
 {
+	if (data->has_error)
+		return False;
+
 	if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) {
 		data->has_error = True;
 		return False;
@@ -309,6 +312,9 @@
 /* work out how many bytes are left in this nested tag */
 int asn1_tag_remaining(ASN1_DATA *data)
 {
+	if (data->has_error)
+		return 0;
+
 	if (!data->nesting) {
 		data->has_error = True;
 		return -1;