buffer overflow code audit.

git-svn-id: file:///svn/unbound/trunk@680 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-10-16 13:03:57 +00:00
parent 4260a18fb1
commit 189fafa1da
6 changed files with 25 additions and 6 deletions

View file

@ -183,6 +183,7 @@ readpid (const char* file)
return -1; return -1;
} }
pidbuf[sizeof(pidbuf)-1] = 0;
pid = (pid_t)strtol(pidbuf, &t, 10); pid = (pid_t)strtol(pidbuf, &t, 10);
if (*t && *t != '\n') { if (*t && *t != '\n') {

View file

@ -2,6 +2,14 @@
- no malloc in log_hex. - no malloc in log_hex.
- assertions around system calls. - assertions around system calls.
- protect against gethostname without ending zero. - protect against gethostname without ending zero.
- ntop output is null terminated by unbound.
- pidfile content null termination
- various snprintf use sizeof(stringbuf) instead of fixed constant.
- changed loopdetect % 8 with & 0x7 since % can become negative for
weird negative input and particular interpretation of integer math.
- dname_pkt_copy checks length of result, to protect result buffers.
prints an error, this should not happen. Bad strings should have
been rejected earlier in the program.
15 October 2007: Wouter 15 October 2007: Wouter
- nicer warning. - nicer warning.

View file

@ -74,6 +74,7 @@ verbose_print_addr(struct addrinfo *addr)
(socklen_t)sizeof(buf)) == 0) { (socklen_t)sizeof(buf)) == 0) {
strncpy(buf, "(null)", sizeof(buf)); strncpy(buf, "(null)", sizeof(buf));
} }
buf[sizeof(buf)-1] = 0;
verbose(VERB_ALGO, "creating %s%s socket %s %d", verbose(VERB_ALGO, "creating %s%s socket %s %d",
addr->ai_socktype==SOCK_DGRAM?"udp": addr->ai_socktype==SOCK_DGRAM?"udp":
addr->ai_socktype==SOCK_STREAM?"tcp":"otherproto", addr->ai_socktype==SOCK_STREAM?"tcp":"otherproto",

View file

@ -152,8 +152,8 @@ loopcheck(uint8_t loop[], size_t pos)
const uint8_t bits[8] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80}; const uint8_t bits[8] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
uint8_t ret; uint8_t ret;
log_assert(pos < MAX_COMPRESS_POS); log_assert(pos < MAX_COMPRESS_POS);
ret = loop[ pos / 8 ] & bits[ pos % 8 ]; ret = loop[ pos / 8 ] & bits[ pos & 0x7 ];
loop[ pos / 8 ] |= bits[ pos % 8 ]; loop[ pos / 8 ] |= bits[ pos & 0x7 ];
return ret; return ret;
} }
@ -305,6 +305,7 @@ dname_pkt_hash(ldns_buffer* pkt, uint8_t* dname, hashvalue_t h)
void dname_pkt_copy(ldns_buffer* pkt, uint8_t* to, uint8_t* dname) void dname_pkt_copy(ldns_buffer* pkt, uint8_t* to, uint8_t* dname)
{ {
/* copy over the dname and decompress it at the same time */ /* copy over the dname and decompress it at the same time */
size_t len = 0;
uint8_t lablen; uint8_t lablen;
lablen = *dname++; lablen = *dname++;
while(lablen) { while(lablen) {
@ -315,6 +316,12 @@ void dname_pkt_copy(ldns_buffer* pkt, uint8_t* to, uint8_t* dname)
continue; continue;
} }
log_assert(lablen <= LDNS_MAX_LABELLEN); log_assert(lablen <= LDNS_MAX_LABELLEN);
len += (size_t)lablen+1;
if(len >= LDNS_MAX_DOMAINLEN) {
*to = 0; /* end the result prematurely */
log_err("bad dname in dname_pkt_copy");
return;
}
*to++ = lablen; *to++ = lablen;
memmove(to, dname, lablen); memmove(to, dname, lablen);
dname += lablen; dname += lablen;

View file

@ -164,6 +164,7 @@ log_addr(const char* str, struct sockaddr_storage* addr, socklen_t addrlen)
if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) { if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
strncpy(dest, "(inet_ntop error)", sizeof(dest)); strncpy(dest, "(inet_ntop error)", sizeof(dest));
} }
dest[sizeof(dest)-1] = 0;
port = ntohs(((struct sockaddr_in*)addr)->sin_port); port = ntohs(((struct sockaddr_in*)addr)->sin_port);
verbose(VERB_DETAIL, "%s %s %s %d (len %d)", verbose(VERB_DETAIL, "%s %s %s %d (len %d)",
str, family, dest, (int)port, (int)addrlen); str, family, dest, (int)port, (int)addrlen);
@ -244,14 +245,14 @@ log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name,
else if(ldns_rr_descript(type) && ldns_rr_descript(type)->_name) else if(ldns_rr_descript(type) && ldns_rr_descript(type)->_name)
ts = ldns_rr_descript(type)->_name; ts = ldns_rr_descript(type)->_name;
else { else {
snprintf(t, 12, "TYPE%d", (int)type); snprintf(t, sizeof(t), "TYPE%d", (int)type);
ts = t; ts = t;
} }
if(ldns_lookup_by_id(ldns_rr_classes, (int)dclass) && if(ldns_lookup_by_id(ldns_rr_classes, (int)dclass) &&
ldns_lookup_by_id(ldns_rr_classes, (int)dclass)->name) ldns_lookup_by_id(ldns_rr_classes, (int)dclass)->name)
cs = ldns_lookup_by_id(ldns_rr_classes, (int)dclass)->name; cs = ldns_lookup_by_id(ldns_rr_classes, (int)dclass)->name;
else { else {
snprintf(c, 12, "CLASS%d", (int)dclass); snprintf(c, sizeof(c), "CLASS%d", (int)dclass);
cs = c; cs = c;
} }
log_info("%s <%s %s %s>", str, buf, ts, cs); log_info("%s <%s %s %s>", str, buf, ts, cs);
@ -279,6 +280,7 @@ void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone,
if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) { if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
strncpy(dest, "(inet_ntop error)", sizeof(dest)); strncpy(dest, "(inet_ntop error)", sizeof(dest));
} }
dest[sizeof(dest)-1] = 0;
port = ntohs(((struct sockaddr_in*)addr)->sin_port); port = ntohs(((struct sockaddr_in*)addr)->sin_port);
dname_str(zone, namebuf); dname_str(zone, namebuf);
if(af != AF_INET && af != AF_INET6) if(af != AF_INET && af != AF_INET6)

View file

@ -510,7 +510,7 @@ region_log_stats(region_type *region)
{ {
char buf[10240], *str=buf; char buf[10240], *str=buf;
int len=0; int len=0;
snprintf(str, 10240, "%lu objects (%lu small/%lu large), %lu bytes allocated (%lu wasted) in %lu chunks, %lu cleanups, %lu in recyclebin%n", snprintf(str, sizeof(buf), "%lu objects (%lu small/%lu large), %lu bytes allocated (%lu wasted) in %lu chunks, %lu cleanups, %lu in recyclebin%n",
(unsigned long) (region->small_objects + region->large_objects), (unsigned long) (region->small_objects + region->large_objects),
(unsigned long) region->small_objects, (unsigned long) region->small_objects,
(unsigned long) region->large_objects, (unsigned long) region->large_objects,
@ -532,7 +532,7 @@ region_log_stats(region_type *region)
el = el->next; el = el->next;
} }
if(i%ALIGNMENT == 0 && i!=0) { if(i%ALIGNMENT == 0 && i!=0) {
snprintf(str, 10240, " %lu%n", snprintf(str, sizeof(buf)-(str-buf), " %lu%n",
(unsigned long)count, &len); (unsigned long)count, &len);
str+=len; str+=len;
} }