Author: bz
Date: Tue Jun 12 12:10:10 2012
New Revision: 236953
URL: http://svn.freebsd.org/changeset/base/236953

Log:
  Fix a problem where zero-length RDATA fields can cause named(8) to crash.
  [12:03]
  
  Correct a privilege escalation when returning from kernel if
  running FreeBSD/amd64 on non-AMD processors. [12:04]
  
  Fix reference count errors in IPv6 code. [EN-12:02]
  
  Security:     CVE-2012-1667
  Security:     FreeBSD-SA-12:03.bind
  Security:     CVE-2012-0217
  Security:     FreeBSD-SA-12:04.sysret
  Security:     FreeBSD-EN-12:02.ipv6refcount
  Approved by:  so (simon, bz)

Modified:
  stable/7/contrib/bind9/lib/dns/rdata.c
  stable/7/contrib/bind9/lib/dns/rdataslab.c
  stable/7/sys/amd64/amd64/trap.c

Changes in other areas also in this revision:
Modified:
  head/sys/amd64/amd64/trap.c
  releng/7.4/UPDATING
  releng/7.4/contrib/bind9/lib/dns/rdata.c
  releng/7.4/contrib/bind9/lib/dns/rdataslab.c
  releng/7.4/sys/amd64/amd64/trap.c
  releng/7.4/sys/conf/newvers.sh
  releng/8.1/UPDATING
  releng/8.1/contrib/bind9/lib/dns/rdata.c
  releng/8.1/contrib/bind9/lib/dns/rdataslab.c
  releng/8.1/sys/amd64/amd64/trap.c
  releng/8.1/sys/conf/newvers.sh
  releng/8.1/sys/netinet/tcp_input.c
  releng/8.1/sys/netinet6/in6.c
  releng/8.1/sys/netinet6/ip6_input.c
  releng/8.2/UPDATING
  releng/8.2/contrib/bind9/lib/dns/rdata.c
  releng/8.2/contrib/bind9/lib/dns/rdataslab.c
  releng/8.2/sys/amd64/amd64/trap.c
  releng/8.2/sys/conf/newvers.sh
  releng/8.2/sys/netinet/tcp_input.c
  releng/8.2/sys/netinet6/in6.c
  releng/8.2/sys/netinet6/ip6_input.c
  releng/8.3/UPDATING
  releng/8.3/contrib/bind9/lib/dns/rdata.c
  releng/8.3/contrib/bind9/lib/dns/rdataslab.c
  releng/8.3/sys/amd64/amd64/trap.c
  releng/8.3/sys/conf/newvers.sh
  releng/8.3/sys/netinet/tcp_input.c
  releng/8.3/sys/netinet6/in6.c
  releng/8.3/sys/netinet6/ip6_input.c
  releng/9.0/UPDATING
  releng/9.0/contrib/bind9/lib/dns/rdata.c
  releng/9.0/contrib/bind9/lib/dns/rdataslab.c
  releng/9.0/sys/amd64/amd64/trap.c
  releng/9.0/sys/conf/newvers.sh
  releng/9.0/sys/netinet/tcp_input.c
  releng/9.0/sys/netinet6/in6.c
  releng/9.0/sys/netinet6/ip6_input.c
  stable/8/sys/amd64/amd64/trap.c
  stable/9/sys/amd64/amd64/trap.c

Modified: stable/7/contrib/bind9/lib/dns/rdata.c
==============================================================================
--- stable/7/contrib/bind9/lib/dns/rdata.c      Tue Jun 12 11:08:51 2012        
(r236952)
+++ stable/7/contrib/bind9/lib/dns/rdata.c      Tue Jun 12 12:10:10 2012        
(r236953)
@@ -334,8 +334,8 @@ dns_rdata_compare(const dns_rdata_t *rda
 
        REQUIRE(rdata1 != NULL);
        REQUIRE(rdata2 != NULL);
-       REQUIRE(rdata1->data != NULL);
-       REQUIRE(rdata2->data != NULL);
+       REQUIRE(rdata1->length == 0 || rdata1->data != NULL);
+       REQUIRE(rdata2->length == 0 || rdata2->data != NULL);
        REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1));
        REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2));
 

Modified: stable/7/contrib/bind9/lib/dns/rdataslab.c
==============================================================================
--- stable/7/contrib/bind9/lib/dns/rdataslab.c  Tue Jun 12 11:08:51 2012        
(r236952)
+++ stable/7/contrib/bind9/lib/dns/rdataslab.c  Tue Jun 12 12:10:10 2012        
(r236953)
@@ -128,6 +128,11 @@ isc_result_t
 dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
                           isc_region_t *region, unsigned int reservelen)
 {
+       /*
+        * Use &removed as a sentinal pointer for duplicate
+        * rdata as rdata.data == NULL is valid.
+        */
+       static unsigned char removed;
        struct xrdata  *x;
        unsigned char  *rawbuf;
 #if DNS_RDATASET_FIXED
@@ -166,6 +171,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_
                INSIST(result == ISC_R_SUCCESS);
                dns_rdata_init(&x[i].rdata);
                dns_rdataset_current(rdataset, &x[i].rdata);
+               INSIST(x[i].rdata.data != &removed);
 #if DNS_RDATASET_FIXED
                x[i].order = i;
 #endif
@@ -198,8 +204,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_
         */
        for (i = 1; i < nalloc; i++) {
                if (compare_rdata(&x[i-1].rdata, &x[i].rdata) == 0) {
-                       x[i-1].rdata.data = NULL;
-                       x[i-1].rdata.length = 0;
+                       x[i-1].rdata.data = &removed;
 #if DNS_RDATASET_FIXED
                        /*
                         * Preserve the least order so A, B, A -> A, B
@@ -275,7 +280,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_
 #endif
 
        for (i = 0; i < nalloc; i++) {
-               if (x[i].rdata.data == NULL)
+               if (x[i].rdata.data == &removed)
                        continue;
 #if DNS_RDATASET_FIXED
                offsettable[x[i].order] = rawbuf - offsetbase;

Modified: stable/7/sys/amd64/amd64/trap.c
==============================================================================
--- stable/7/sys/amd64/amd64/trap.c     Tue Jun 12 11:08:51 2012        
(r236952)
+++ stable/7/sys/amd64/amd64/trap.c     Tue Jun 12 12:10:10 2012        
(r236953)
@@ -972,6 +972,23 @@ syscall(struct trapframe *frame)
        /*
         * Traced syscall.
         */
+
+       /*
+        * If the user-supplied value of %rip is not a canonical
+        * address, then some CPUs will trigger a ring 0 #GP during
+        * the sysret instruction.  However, the fault handler would
+        * execute with the user's %gs and %rsp in ring 0 which would
+        * not be safe.  Instead, preemptively kill the thread with a
+        * SIGBUS.
+        */
+       if (td->td_frame->tf_rip >= VM_MAXUSER_ADDRESS) {
+               ksiginfo_init_trap(&ksi);
+               ksi.ksi_signo = SIGBUS;
+               ksi.ksi_code = BUS_OBJERR;
+               ksi.ksi_trapno = T_PROTFLT;
+               ksi.ksi_addr = (void *)td->td_frame->tf_rip;
+               trapsignal(td, &ksi);
+       }
        if (orig_tf_rflags & PSL_T) {
                frame->tf_rflags &= ~PSL_T;
                ksiginfo_init_trap(&ksi);
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to