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

Add in bufflen limit when storing NetBIOS names. Remove safe_strcpy.

This commit is contained in:
Jeremy Allison 2011-05-03 14:52:01 -07:00
parent 6f7c4a0539
commit a3e913ae8b

View File

@ -288,7 +288,7 @@ void put_name(char *dest, const char *name, int pad, unsigned int name_type)
If buf == NULL this is a length calculation.
******************************************************************/
static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
static int put_nmb_name(char *buf, size_t buflen, int offset,struct nmb_name *name)
{
int ret,m;
nstring buf1;
@ -302,6 +302,9 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
}
if (buf) {
if (offset >= buflen) {
return 0;
}
buf[offset] = 0x20;
}
@ -309,6 +312,9 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
for (m=0;m<MAX_NETBIOSNAME_LEN;m++) {
if (buf) {
if (offset+2+2*m >= buflen) {
return 0;
}
buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
}
@ -316,20 +322,30 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
offset += 33;
if (buf) {
if (offset >= buflen) {
return 0;
}
buf[offset] = 0;
}
if (name->scope[0]) {
/* XXXX this scope handling needs testing */
ret += strlen(name->scope) + 1;
size_t scopenamelen = strlen(name->scope) + 1;
ret += scopenamelen;
if (buf) {
safe_strcpy(&buf[offset+1],name->scope,
sizeof(name->scope));
if (offset+1+scopenamelen >= buflen) {
return 0;
}
strlcpy(&buf[offset+1],name->scope,
buflen - (offset+1));
p = &buf[offset+1];
while ((p = strchr_m(p,'.'))) {
buf[offset] = PTR_DIFF(p,&buf[offset+1]);
offset += (buf[offset] + 1);
if (offset+1 >= buflen) {
return 0;
}
p = &buf[offset+1];
}
buf[offset] = strlen(&buf[offset+1]);
@ -404,13 +420,13 @@ static bool parse_alloc_res_rec(char *inbuf,int *offset,int length,
If buf == NULL this is a length calculation.
******************************************************************/
static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
static int put_res_rec(char *buf, size_t buflen, int offset,struct res_rec *recs,int count)
{
int ret=0;
int i;
for (i=0;i<count;i++) {
int l = put_nmb_name(buf,offset,&recs[i].rr_name);
int l = put_nmb_name(buf,buflen,offset,&recs[i].rr_name);
offset += l;
ret += l;
if (buf) {
@ -887,8 +903,8 @@ static int build_dgram(char *buf, size_t len, struct dgram_packet *dgram)
if (dgram->header.msg_type == 0x10 ||
dgram->header.msg_type == 0x11 ||
dgram->header.msg_type == 0x12) {
offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
offset += put_nmb_name((char *)ubuf,len,offset,&dgram->source_name);
offset += put_nmb_name((char *)ubuf,len,offset,&dgram->dest_name);
}
if (buf) {
@ -979,13 +995,13 @@ static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb)
/* XXXX this doesn't handle a qdcount of > 1 */
if (len) {
/* Length check. */
int extra = put_nmb_name(NULL,offset,
int extra = put_nmb_name(NULL,0,offset,
&nmb->question.question_name);
if (offset + extra > len) {
return 0;
}
}
offset += put_nmb_name((char *)ubuf,offset,
offset += put_nmb_name((char *)ubuf,len,offset,
&nmb->question.question_name);
if (buf) {
RSSVAL(ubuf,offset,nmb->question.question_type);
@ -997,26 +1013,26 @@ static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb)
if (nmb->header.ancount) {
if (len) {
/* Length check. */
int extra = put_res_rec(NULL,offset,nmb->answers,
int extra = put_res_rec(NULL,0,offset,nmb->answers,
nmb->header.ancount);
if (offset + extra > len) {
return 0;
}
}
offset += put_res_rec((char *)ubuf,offset,nmb->answers,
offset += put_res_rec((char *)ubuf,len,offset,nmb->answers,
nmb->header.ancount);
}
if (nmb->header.nscount) {
if (len) {
/* Length check. */
int extra = put_res_rec(NULL,offset,nmb->nsrecs,
int extra = put_res_rec(NULL,0,offset,nmb->nsrecs,
nmb->header.nscount);
if (offset + extra > len) {
return 0;
}
}
offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
offset += put_res_rec((char *)ubuf,len,offset,nmb->nsrecs,
nmb->header.nscount);
}
@ -1048,13 +1064,13 @@ static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb)
} else if (nmb->header.arcount) {
if (len) {
/* Length check. */
int extra = put_res_rec(NULL,offset,nmb->additional,
int extra = put_res_rec(NULL,0,offset,nmb->additional,
nmb->header.arcount);
if (offset + extra > len) {
return 0;
}
}
offset += put_res_rec((char *)ubuf,offset,nmb->additional,
offset += put_res_rec((char *)ubuf,len,offset,nmb->additional,
nmb->header.arcount);
}
return offset;