aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacques Vidrine <nectar@FreeBSD.org>2002-11-14 05:15:15 +0000
committerJacques Vidrine <nectar@FreeBSD.org>2002-11-14 05:15:15 +0000
commit4efedce3110be65663620c13a9fa51c910bb881f (patch)
tree920314816e26486ef7480d021434fb182c9b7a27
parentb83144c2b06ad8455f451f2179ca7f94fe32a306 (diff)
downloadsrc-4efedce3110be65663620c13a9fa51c910bb881f.tar.gz
src-4efedce3110be65663620c13a9fa51c910bb881f.zip
Correct recent name server vulnerabilities as documented at
Notes
Notes: svn path=/releng/4.4/; revision=106897
-rw-r--r--UPDATING9
-rw-r--r--contrib/bind/CHANGES20
-rw-r--r--contrib/bind/bin/named/db_defs.h2
-rw-r--r--contrib/bind/bin/named/db_sec.c14
-rw-r--r--contrib/bind/bin/named/ns_defs.h2
-rw-r--r--contrib/bind/bin/named/ns_ncache.c13
-rw-r--r--contrib/bind/bin/named/ns_req.c2
-rw-r--r--contrib/bind/bin/named/ns_resp.c16
-rw-r--r--contrib/bind/lib/nameser/ns_name.c4
-rw-r--r--contrib/bind/lib/nameser/ns_samedomain.c2
-rw-r--r--sys/conf/newvers.sh2
11 files changed, 64 insertions, 22 deletions
diff --git a/UPDATING b/UPDATING
index ca99d5689a09..b2b3d79dcc8f 100644
--- a/UPDATING
+++ b/UPDATING
@@ -17,13 +17,16 @@ minimal number of processes, if possible, for that patch. For those
updates that don't have an advisory, or to be safe, you can do a full
build and install as described in the COMMON ITEMS section.
-20021026: p29
+20021113: p30 FreeBSD-SA-02:43.bind
+ Correct name server vulnerabilities.
+
+20021026: p29 FreeBSD-SA-02:41.smrsh
smrsh bypass bug.
-20021023: p28
+20021023: p28 FreeBSD-SA-02:40.kadmind
Correct kadmind buffer overflow.
-20020911: p27
+20020911: p27 FreeBSD-SA-02:39.libkvm
The kvm_openfiles/kvm_open functions now mark the returned file
descriptors close-on-exec in case set-user-ID/set-group-ID
applications are careless.
diff --git a/contrib/bind/CHANGES b/contrib/bind/CHANGES
index 25ea08f4d5b6..344d95a628fb 100644
--- a/contrib/bind/CHANGES
+++ b/contrib/bind/CHANGES
@@ -1,3 +1,23 @@
+1469. [bug] buffer length calculation for PX was wrong.
+
+1468. [bug] ns_name_ntol() could overwite a zero length buffer.
+
+1467. [bug] off by one bug in ns_makecannon().
+
+1466. [bug] large ENDS UDP buffer size could trigger a assertion.
+
+1465. [bug] possible NULL pointer dereference in db_sec.c
+
+1464. [bug] the buffer used to construct the -ve record was not
+ big enough for all possible SOA records. use pointer
+ arithmetic to calculate the remaining size in this
+ buffer.
+
+1463. [bug] use serial space arithmetic to determine if a SIG is
+ too old, in the future or has internally constistant
+ times.
+
+1462. [bug] write buffer overflow in make_rr().
--- 8.3.3-REL released --- (Wed Jun 26 21:15:43 PDT 2002)
diff --git a/contrib/bind/bin/named/db_defs.h b/contrib/bind/bin/named/db_defs.h
index 68869f023cb7..af00bb158965 100644
--- a/contrib/bind/bin/named/db_defs.h
+++ b/contrib/bind/bin/named/db_defs.h
@@ -78,7 +78,7 @@
*/
/* max length of data in RR data field */
-#define MAXDATA (2*MAXDNAME + 5*INT32SZ)
+#define MAXDATA (3*MAXDNAME + 5*INT32SZ)
/* max length of data in a TXT RR segment */
#define MAXCHARSTRING 255
diff --git a/contrib/bind/bin/named/db_sec.c b/contrib/bind/bin/named/db_sec.c
index 2d3425dbf4a8..0ce0d9fa5238 100644
--- a/contrib/bind/bin/named/db_sec.c
+++ b/contrib/bind/bin/named/db_sec.c
@@ -479,7 +479,9 @@ verify_set(struct db_rrset *rrset) {
struct sig_record *sigdata;
struct dnode *sigdn;
struct databuf *sigdp;
- time_t now;
+ u_int32_t now;
+ u_int32_t exptime;
+ u_int32_t signtime;
char *signer;
u_char name_n[MAXDNAME];
u_char *sig, *eom;
@@ -492,6 +494,7 @@ verify_set(struct db_rrset *rrset) {
int dnssec_failed = 0, dnssec_succeeded = 0;
int return_value;
int i;
+ int expired = 0;
if (rrset == NULL || rrset->rr_name == NULL) {
ns_warning (ns_log_default, "verify_set: missing rrset/name");
@@ -527,11 +530,14 @@ verify_set(struct db_rrset *rrset) {
* Don't verify a set if the SIG inception time is in
* the future. This should be fixed before 2038 (BEW)
*/
- if ((time_t)ntohl(sigdata->sig_time_n) > now)
+ signtime = ntohl(sigdata->sig_time_n);
+ if (SEQ_GT(signtime, now))
continue;
/* An expired set is dropped, but the data is not. */
- if ((time_t)ntohl(sigdata->sig_exp_n) < now) {
+ exptime = ntohl(sigdata->sig_exp_n);
+ if (SEQ_GT(now, exptime)) {
+ expired++;
db_detach(&sigdn->dp);
sigdp = NULL;
continue;
@@ -723,7 +729,7 @@ verify_set(struct db_rrset *rrset) {
}
end:
- if (dnssec_failed > 0)
+ if (dnssec_failed > 0 || expired > 0)
rrset_trim_sigs(rrset);
if (trustedkey == 0 && key != NULL)
dst_free_key(key);
diff --git a/contrib/bind/bin/named/ns_defs.h b/contrib/bind/bin/named/ns_defs.h
index f8bb976a2faf..c99c1529f785 100644
--- a/contrib/bind/bin/named/ns_defs.h
+++ b/contrib/bind/bin/named/ns_defs.h
@@ -469,7 +469,7 @@ struct qinfo {
q_cmsglen, /* len of cname message */
q_cmsgsize; /* allocated size of cname message */
int16_t q_dfd; /* UDP file descriptor */
- int16_t q_udpsize; /* UDP message size */
+ u_int16_t q_udpsize; /* UDP message size */
int q_distance; /* distance this query is from the
* original query that the server
* received. */
diff --git a/contrib/bind/bin/named/ns_ncache.c b/contrib/bind/bin/named/ns_ncache.c
index 5667f367f935..9ca34996d96c 100644
--- a/contrib/bind/bin/named/ns_ncache.c
+++ b/contrib/bind/bin/named/ns_ncache.c
@@ -66,7 +66,7 @@ cache_n_resp(u_char *msg, int msglen, struct sockaddr_in from,
u_int16_t atype;
u_char *sp, *cp1;
u_char data[MAXDATA];
- size_t len = sizeof data;
+ u_char *eod = data + sizeof(data);
#endif
nameserIncr(from.sin_addr, nssRcvdNXD);
@@ -186,7 +186,7 @@ cache_n_resp(u_char *msg, int msglen, struct sockaddr_in from,
rdatap = cp;
/* origin */
- n = dn_expand(msg, msg + msglen, cp, (char*)data, len);
+ n = dn_expand(msg, msg + msglen, cp, (char*)data, eod - data);
if (n < 0) {
ns_debug(ns_log_ncache, 3,
"ncache: origin form error");
@@ -195,9 +195,8 @@ cache_n_resp(u_char *msg, int msglen, struct sockaddr_in from,
cp += n;
n = strlen((char*)data) + 1;
cp1 = data + n;
- len -= n;
/* mail */
- n = dn_expand(msg, msg + msglen, cp, (char*)cp1, len);
+ n = dn_expand(msg, msg + msglen, cp, (char*)cp1, eod - cp1);
if (n < 0) {
ns_debug(ns_log_ncache, 3, "ncache: mail form error");
return;
@@ -205,20 +204,20 @@ cache_n_resp(u_char *msg, int msglen, struct sockaddr_in from,
cp += n;
n = strlen((char*)cp1) + 1;
cp1 += n;
- len -= n;
n = 5 * INT32SZ;
+ if (n > (eod - cp1)) /* Can't happen. See MAXDATA. */
+ return;
BOUNDS_CHECK(cp, n);
memcpy(cp1, cp, n);
/* serial, refresh, retry, expire, min */
cp1 += n;
- len -= n;
cp += n;
if (cp != rdatap + dlen) {
ns_debug(ns_log_ncache, 3, "ncache: form error");
return;
}
/* store the zone of the soa record */
- n = dn_expand(msg, msg + msglen, sp, (char*)cp1, len);
+ n = dn_expand(msg, msg + msglen, sp, (char*)cp1, eod - cp1);
if (n < 0) {
ns_debug(ns_log_ncache, 3, "ncache: form error 2");
return;
diff --git a/contrib/bind/bin/named/ns_req.c b/contrib/bind/bin/named/ns_req.c
index 6aca04a73e97..42039f9c3bae 100644
--- a/contrib/bind/bin/named/ns_req.c
+++ b/contrib/bind/bin/named/ns_req.c
@@ -2195,7 +2195,7 @@ make_rr(const char *name, struct databuf *dp, u_char *buf,
/* first just copy over the type_covered, algorithm, */
/* labels, orig ttl, two timestamps, and the footprint */
- if ((dp->d_size - 18) > buflen)
+ if (buflen < 18)
goto cleanup; /* out of room! */
memcpy(cp, cp1, 18);
cp += 18;
diff --git a/contrib/bind/bin/named/ns_resp.c b/contrib/bind/bin/named/ns_resp.c
index 91a38694ef4a..c371fba842af 100644
--- a/contrib/bind/bin/named/ns_resp.c
+++ b/contrib/bind/bin/named/ns_resp.c
@@ -2001,7 +2001,7 @@ rrextract(u_char *msg, int msglen, u_char *rrp, struct databuf **dpp,
* to BOUNDS_CHECK() here.
*/
cp1 += (n = strlen((char *)cp1) + 1);
- n1 = sizeof(data) - n;
+ n1 = sizeof(data) - n - INT16SZ;
n = dn_expand(msg, eom, cp, (char *)cp1, n1);
if (n < 0) {
hp->rcode = FORMERR;
@@ -2043,8 +2043,18 @@ rrextract(u_char *msg, int msglen, u_char *rrp, struct databuf **dpp,
ttl = origTTL;
}
+ /*
+ * Check that expire and signature times are internally
+ * consistant.
+ */
+ if (!SEQ_GT(exptime, signtime) && exptime != signtime) {
+ ns_debug(ns_log_default, 3,
+ "ignoring SIG: signature expires before it was signed");
+ return ((cp - rrp) + dlen);
+ }
+
/* Don't let bogus signers "sign" in the future. */
- if (signtime > now) {
+ if (SEQ_GT(signtime, now)) {
ns_debug(ns_log_default, 3,
"ignoring SIG: signature date %s is in the future",
p_secstodate (signtime));
@@ -2052,7 +2062,7 @@ rrextract(u_char *msg, int msglen, u_char *rrp, struct databuf **dpp,
}
/* Ignore received SIG RR's that are already expired. */
- if (exptime <= now) {
+ if (SEQ_GT(now, exptime)) {
ns_debug(ns_log_default, 3,
"ignoring SIG: expiration %s is in the past",
p_secstodate (exptime));
diff --git a/contrib/bind/lib/nameser/ns_name.c b/contrib/bind/lib/nameser/ns_name.c
index 96c41e873659..6b193f6160db 100644
--- a/contrib/bind/lib/nameser/ns_name.c
+++ b/contrib/bind/lib/nameser/ns_name.c
@@ -341,6 +341,10 @@ ns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz)
dn = dst;
eom = dst + dstsiz;
+ if (dn >= eom) {
+ errno = EMSGSIZE;
+ return (-1);
+ }
while ((n = *cp++) != 0) {
if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
/* Some kind of compression pointer. */
diff --git a/contrib/bind/lib/nameser/ns_samedomain.c b/contrib/bind/lib/nameser/ns_samedomain.c
index c8479249b55f..e29a8f8422ab 100644
--- a/contrib/bind/lib/nameser/ns_samedomain.c
+++ b/contrib/bind/lib/nameser/ns_samedomain.c
@@ -166,7 +166,7 @@ int
ns_makecanon(const char *src, char *dst, size_t dstsize) {
size_t n = strlen(src);
- if (n + sizeof "." > dstsize) {
+ if (n + sizeof "." + 1 > dstsize) {
errno = EMSGSIZE;
return (-1);
}
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index a2d42fa94f23..227bc36753e0 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -36,7 +36,7 @@
TYPE="FreeBSD"
REVISION="4.4"
-BRANCH="RELEASE-p29"
+BRANCH="RELEASE-p30"
RELEASE="${REVISION}-${BRANCH}"
VERSION="${TYPE} ${RELEASE}"