1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-28 01:58:17 +03:00

r2224: Make nmbd more robust against bad netbios packets.

Jeremy.
(This used to be commit dd9b17abd6b32c090840c1a0b797fd774711cb3a)
This commit is contained in:
Jeremy Allison 2004-09-04 01:57:16 +00:00 committed by Gerald (Jerry) Carter
parent b755bdaa8e
commit 571cc4811b
3 changed files with 146 additions and 7 deletions

View File

@ -475,6 +475,11 @@ static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
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);
}

View File

@ -1203,6 +1203,16 @@ an error packet of type %x\n", nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip),
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 @@ an error packet of type %x\n", nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip),
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",

View File

@ -102,8 +102,22 @@ logons are not enabled.\n", inet_ntoa(p->ip) ));
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 @@ logons are not enabled.\n", inet_ntoa(p->ip) ));
}
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 @@ logons are not enabled.\n", inet_ntoa(p->ip) ));
} 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 @@ logons are not enabled.\n", inet_ntoa(p->ip) ));
}
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 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
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 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
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 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
/* 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 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
/* 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);