Author: cperciva
Date: Fri Dec 23 15:00:37 2011
New Revision: 228843
URL: http://svn.freebsd.org/changeset/base/228843

Log:
  Fix a problem whereby a corrupt DNS record can cause named to crash. [11:06]
  
  Add an API for alerting internal libc routines to the presence of
  "unsafe" paths post-chroot, and use it in ftpd. [11:07]
  
  Fix a buffer overflow in telnetd. [11:08]
  
  Make pam_ssh ignore unpassphrased keys unless the "nullok" option is
  specified. [11:09]
  
  Add sanity checking of service names in pam_start. [11:10]
  
  Approved by:    so (cperciva)
  Approved by:    re (bz)
  Security:       FreeBSD-SA-11:06.bind
  Security:       FreeBSD-SA-11:07.chroot
  Security:       FreeBSD-SA-11:08.telnetd
  Security:       FreeBSD-SA-11:09.pam_ssh
  Security:       FreeBSD-SA-11:10.pam

Added:
  releng/7.3/lib/libc/gen/libc_dlopen.c   (contents, props changed)
  releng/7.4/lib/libc/gen/libc_dlopen.c   (contents, props changed)
  releng/8.1/lib/libc/gen/libc_dlopen.c   (contents, props changed)
  releng/8.2/lib/libc/gen/libc_dlopen.c   (contents, props changed)
  releng/9.0/lib/libc/gen/libc_dlopen.c   (contents, props changed)
Modified:
  releng/7.3/UPDATING
  releng/7.3/contrib/bind9/bin/named/query.c
  releng/7.3/contrib/bind9/lib/dns/rbtdb.c
  releng/7.3/contrib/openpam/lib/openpam_configure.c
  releng/7.3/contrib/telnet/libtelnet/encrypt.c
  releng/7.3/crypto/heimdal/appl/telnet/libtelnet/encrypt.c
  releng/7.3/include/unistd.h
  releng/7.3/lib/libc/Versions.def
  releng/7.3/lib/libc/gen/Makefile.inc
  releng/7.3/lib/libc/gen/Symbol.map
  releng/7.3/lib/libc/include/libc_private.h
  releng/7.3/lib/libc/net/nsdispatch.c
  releng/7.3/lib/libpam/modules/pam_ssh/pam_ssh.c
  releng/7.3/libexec/ftpd/ftpd.c
  releng/7.3/libexec/ftpd/popen.c
  releng/7.3/sys/conf/newvers.sh
  releng/7.4/UPDATING
  releng/7.4/contrib/bind9/bin/named/query.c
  releng/7.4/contrib/bind9/lib/dns/rbtdb.c
  releng/7.4/contrib/openpam/lib/openpam_configure.c
  releng/7.4/contrib/telnet/libtelnet/encrypt.c
  releng/7.4/crypto/heimdal/appl/telnet/libtelnet/encrypt.c
  releng/7.4/include/unistd.h
  releng/7.4/lib/libc/Versions.def
  releng/7.4/lib/libc/gen/Makefile.inc
  releng/7.4/lib/libc/gen/Symbol.map
  releng/7.4/lib/libc/include/libc_private.h
  releng/7.4/lib/libc/net/nsdispatch.c
  releng/7.4/lib/libpam/modules/pam_ssh/pam_ssh.c
  releng/7.4/libexec/ftpd/ftpd.c
  releng/7.4/libexec/ftpd/popen.c
  releng/7.4/sys/conf/newvers.sh
  releng/8.1/UPDATING
  releng/8.1/contrib/bind9/bin/named/query.c
  releng/8.1/contrib/bind9/lib/dns/rbtdb.c
  releng/8.1/contrib/openpam/lib/openpam_configure.c
  releng/8.1/contrib/telnet/libtelnet/encrypt.c
  releng/8.1/crypto/heimdal/appl/telnet/libtelnet/encrypt.c
  releng/8.1/include/unistd.h
  releng/8.1/lib/libc/Versions.def
  releng/8.1/lib/libc/gen/Makefile.inc
  releng/8.1/lib/libc/gen/Symbol.map
  releng/8.1/lib/libc/include/libc_private.h
  releng/8.1/lib/libc/net/nsdispatch.c
  releng/8.1/lib/libpam/modules/pam_ssh/pam_ssh.c
  releng/8.1/libexec/ftpd/ftpd.c
  releng/8.1/libexec/ftpd/popen.c
  releng/8.1/sys/conf/newvers.sh
  releng/8.2/UPDATING
  releng/8.2/contrib/bind9/bin/named/query.c
  releng/8.2/contrib/bind9/lib/dns/rbtdb.c
  releng/8.2/contrib/openpam/lib/openpam_configure.c
  releng/8.2/contrib/telnet/libtelnet/encrypt.c
  releng/8.2/crypto/heimdal/appl/telnet/libtelnet/encrypt.c
  releng/8.2/include/unistd.h
  releng/8.2/lib/libc/Versions.def
  releng/8.2/lib/libc/gen/Makefile.inc
  releng/8.2/lib/libc/gen/Symbol.map
  releng/8.2/lib/libc/include/libc_private.h
  releng/8.2/lib/libc/net/nsdispatch.c
  releng/8.2/lib/libpam/modules/pam_ssh/pam_ssh.c
  releng/8.2/libexec/ftpd/ftpd.c
  releng/8.2/libexec/ftpd/popen.c
  releng/8.2/sys/conf/newvers.sh
  releng/9.0/contrib/telnet/libtelnet/encrypt.c
  releng/9.0/crypto/heimdal/appl/telnet/libtelnet/encrypt.c
  releng/9.0/include/unistd.h
  releng/9.0/lib/libc/Versions.def
  releng/9.0/lib/libc/gen/Makefile.inc
  releng/9.0/lib/libc/gen/Symbol.map
  releng/9.0/lib/libc/iconv/citrus_module.c
  releng/9.0/lib/libc/include/libc_private.h
  releng/9.0/lib/libc/net/nsdispatch.c
  releng/9.0/libexec/ftpd/ftpd.c
  releng/9.0/libexec/ftpd/popen.c

Changes in other areas also in this revision:
Added:
  head/lib/libc/gen/libc_dlopen.c   (contents, props changed)
  stable/7/lib/libc/gen/libc_dlopen.c   (contents, props changed)
  stable/8/lib/libc/gen/libc_dlopen.c   (contents, props changed)
  stable/9/lib/libc/gen/libc_dlopen.c   (contents, props changed)
Modified:
  head/contrib/telnet/libtelnet/encrypt.c
  head/crypto/heimdal/appl/telnet/libtelnet/encrypt.c
  head/include/unistd.h
  head/lib/libc/gen/Makefile.inc
  head/lib/libc/gen/Symbol.map
  head/lib/libc/iconv/citrus_module.c
  head/lib/libc/include/libc_private.h
  head/lib/libc/net/nsdispatch.c
  head/libexec/ftpd/ftpd.c
  head/libexec/ftpd/popen.c
  stable/7/contrib/telnet/libtelnet/encrypt.c
  stable/7/crypto/heimdal/appl/telnet/libtelnet/encrypt.c
  stable/7/include/unistd.h
  stable/7/lib/libc/Versions.def
  stable/7/lib/libc/gen/Makefile.inc
  stable/7/lib/libc/gen/Symbol.map
  stable/7/lib/libc/include/libc_private.h
  stable/7/lib/libc/net/nsdispatch.c
  stable/7/libexec/ftpd/ftpd.c
  stable/7/libexec/ftpd/popen.c
  stable/8/contrib/telnet/libtelnet/encrypt.c
  stable/8/crypto/heimdal/appl/telnet/libtelnet/encrypt.c
  stable/8/include/unistd.h
  stable/8/lib/libc/Versions.def
  stable/8/lib/libc/gen/Makefile.inc
  stable/8/lib/libc/gen/Symbol.map
  stable/8/lib/libc/include/libc_private.h
  stable/8/lib/libc/net/nsdispatch.c
  stable/8/libexec/ftpd/ftpd.c
  stable/8/libexec/ftpd/popen.c
  stable/9/contrib/telnet/libtelnet/encrypt.c
  stable/9/crypto/heimdal/appl/telnet/libtelnet/encrypt.c
  stable/9/include/unistd.h
  stable/9/lib/libc/Versions.def
  stable/9/lib/libc/gen/Makefile.inc
  stable/9/lib/libc/gen/Symbol.map
  stable/9/lib/libc/iconv/citrus_module.c
  stable/9/lib/libc/include/libc_private.h
  stable/9/lib/libc/net/nsdispatch.c
  stable/9/libexec/ftpd/ftpd.c
  stable/9/libexec/ftpd/popen.c

Modified: releng/7.3/UPDATING
==============================================================================
--- releng/7.3/UPDATING Fri Dec 23 14:39:30 2011        (r228842)
+++ releng/7.3/UPDATING Fri Dec 23 15:00:37 2011        (r228843)
@@ -8,6 +8,22 @@ Items affecting the ports and packages s
 /usr/ports/UPDATING.  Please read that file before running
 portupgrade.
 
+20111223:      p9      FreeBSD-SA-11:06.bind, FreeBSD-SA-11:07.chroot
+                       FreeBSD-SA-11:08.telnetd, FreeBSD-SA-11:09.pam_ssh
+                       FreeBSD-SA-11:10.pam
+       Fix a problem whereby a corrupt DNS record can cause named to crash.
+       [11:06]
+
+       Add an API for alerting internal libc routines to the presence of
+       "unsafe" paths post-chroot, and use it in ftpd. [11:07]
+
+       Fix a buffer overflow in telnetd. [11:08]
+
+       Make pam_ssh ignore unpassphrased keys unless the "nullok" option is
+       specified. [11:09]
+
+       Add sanity checking of service names in pam_start. [11:10]
+
 20111004:      p8      FreeBSD-SA-11:05.unix (revised)
        Fix a bug in UNIX socket handling in the linux emulator which was
        exposed by the security fix in FreeBSD-SA-11:05.unix.

Modified: releng/7.3/contrib/bind9/bin/named/query.c
==============================================================================
--- releng/7.3/contrib/bind9/bin/named/query.c  Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.3/contrib/bind9/bin/named/query.c  Fri Dec 23 15:00:37 2011        
(r228843)
@@ -1250,11 +1250,9 @@ query_addadditional(void *arg, dns_name_
                        goto addname;
                if (result == DNS_R_NCACHENXRRSET) {
                        dns_rdataset_disassociate(rdataset);
-                       /*
-                        * Negative cache entries don't have sigrdatasets.
-                        */
-                       INSIST(sigrdataset == NULL ||
-                              ! dns_rdataset_isassociated(sigrdataset));
+                       if (sigrdataset != NULL &&
+                           dns_rdataset_isassociated(sigrdataset))
+                               dns_rdataset_disassociate(sigrdataset);
                }
                if (result == ISC_R_SUCCESS) {
                        mname = NULL;
@@ -1295,8 +1293,9 @@ query_addadditional(void *arg, dns_name_
                        goto addname;
                if (result == DNS_R_NCACHENXRRSET) {
                        dns_rdataset_disassociate(rdataset);
-                       INSIST(sigrdataset == NULL ||
-                              ! dns_rdataset_isassociated(sigrdataset));
+                       if (sigrdataset != NULL &&
+                           dns_rdataset_isassociated(sigrdataset))
+                               dns_rdataset_disassociate(sigrdataset);
                }
                if (result == ISC_R_SUCCESS) {
                        mname = NULL;
@@ -1744,10 +1743,8 @@ query_addadditional2(void *arg, dns_name
                goto setcache;
        if (result == DNS_R_NCACHENXRRSET) {
                dns_rdataset_disassociate(rdataset);
-               /*
-                * Negative cache entries don't have sigrdatasets.
-                */
-               INSIST(! dns_rdataset_isassociated(sigrdataset));
+               if (dns_rdataset_isassociated(sigrdataset))
+                       dns_rdataset_disassociate(sigrdataset);
        }
        if (result == ISC_R_SUCCESS) {
                /* Remember the result as a cache */

Modified: releng/7.3/contrib/bind9/lib/dns/rbtdb.c
==============================================================================
--- releng/7.3/contrib/bind9/lib/dns/rbtdb.c    Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.3/contrib/bind9/lib/dns/rbtdb.c    Fri Dec 23 15:00:37 2011        
(r228843)
@@ -244,6 +244,7 @@ typedef struct rdatasetheader {
 #define RDATASET_ATTR_IGNORE           0x0004
 #define RDATASET_ATTR_RETAIN           0x0008
 #define RDATASET_ATTR_NXDOMAIN         0x0010
+#define RDATASET_ATTR_NEGATIVE         0x0100
 
 typedef struct acache_cbarg {
        dns_rdatasetadditional_t        type;
@@ -278,6 +279,8 @@ struct acachectl {
        (((header)->attributes & RDATASET_ATTR_RETAIN) != 0)
 #define NXDOMAIN(header) \
        (((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0)
+#define NEGATIVE(header) \
+       (((header)->attributes & RDATASET_ATTR_NEGATIVE) != 0)
 
 #define DEFAULT_NODE_LOCK_COUNT                7       /*%< Should be prime. */
 #define DEFAULT_CACHE_NODE_LOCK_COUNT  1009    /*%< Should be prime. */
@@ -3656,7 +3659,7 @@ cache_find(dns_db_t *db, dns_name_t *nam
            result == DNS_R_NCACHENXRRSET) {
                bind_rdataset(search.rbtdb, node, found, search.now,
                              rdataset);
-               if (foundsig != NULL)
+               if (!NEGATIVE(found) && foundsig != NULL)
                        bind_rdataset(search.rbtdb, node, foundsig, search.now,
                                      sigrdataset);
        }
@@ -4242,7 +4245,7 @@ cache_findrdataset(dns_db_t *db, dns_dbn
        }
        if (found != NULL) {
                bind_rdataset(rbtdb, rbtnode, found, now, rdataset);
-               if (foundsig != NULL)
+               if (!NEGATIVE(found) && foundsig != NULL)
                        bind_rdataset(rbtdb, rbtnode, foundsig, now,
                                      sigrdataset);
        }

Modified: releng/7.3/contrib/openpam/lib/openpam_configure.c
==============================================================================
--- releng/7.3/contrib/openpam/lib/openpam_configure.c  Fri Dec 23 14:39:30 
2011        (r228842)
+++ releng/7.3/contrib/openpam/lib/openpam_configure.c  Fri Dec 23 15:00:37 
2011        (r228843)
@@ -285,6 +285,13 @@ openpam_load_chain(pam_handle_t *pamh,
        size_t len;
        int r;
 
+       /* don't allow to escape from policy_path */
+       if (strchr(service, '/')) {
+               openpam_log(PAM_LOG_ERROR, "invalid service name: %s",
+                   service);
+               return (-PAM_SYSTEM_ERR);
+       }
+
        for (path = openpam_policy_path; *path != NULL; ++path) {
                len = strlen(*path);
                if ((*path)[len - 1] == '/') {

Modified: releng/7.3/contrib/telnet/libtelnet/encrypt.c
==============================================================================
--- releng/7.3/contrib/telnet/libtelnet/encrypt.c       Fri Dec 23 14:39:30 
2011        (r228842)
+++ releng/7.3/contrib/telnet/libtelnet/encrypt.c       Fri Dec 23 15:00:37 
2011        (r228843)
@@ -721,6 +721,9 @@ encrypt_keyid(struct key_info *kp, unsig
        int dir = kp->dir;
        int ret = 0;
 
+       if (len > MAXKEYLEN)
+               len = MAXKEYLEN;
+
        if (!(ep = (*kp->getcrypt)(*kp->modep))) {
                if (len == 0)
                        return;

Modified: releng/7.3/crypto/heimdal/appl/telnet/libtelnet/encrypt.c
==============================================================================
--- releng/7.3/crypto/heimdal/appl/telnet/libtelnet/encrypt.c   Fri Dec 23 
14:39:30 2011        (r228842)
+++ releng/7.3/crypto/heimdal/appl/telnet/libtelnet/encrypt.c   Fri Dec 23 
15:00:37 2011        (r228843)
@@ -736,6 +736,9 @@ encrypt_keyid(struct key_info *kp, unsig
     int dir = kp->dir;
     int ret = 0;
 
+    if (len > MAXKEYLEN)
+        len = MAXKEYLEN;
+
     if (!(ep = (*kp->getcrypt)(*kp->modep))) {
        if (len == 0)
            return;

Modified: releng/7.3/include/unistd.h
==============================================================================
--- releng/7.3/include/unistd.h Fri Dec 23 14:39:30 2011        (r228842)
+++ releng/7.3/include/unistd.h Fri Dec 23 15:00:37 2011        (r228843)
@@ -494,6 +494,7 @@ int  initgroups(const char *, gid_t);
 int     iruserok(unsigned long, int, const char *, const char *);
 int     iruserok_sa(const void *, int, int, const char *, const char *);
 int     issetugid(void);
+void   __FreeBSD_libc_enter_restricted_mode(void);
 char   *mkdtemp(char *);
 #ifndef        _MKNOD_DECLARED
 int     mknod(const char *, mode_t, dev_t);

Modified: releng/7.3/lib/libc/Versions.def
==============================================================================
--- releng/7.3/lib/libc/Versions.def    Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.3/lib/libc/Versions.def    Fri Dec 23 15:00:37 2011        
(r228843)
@@ -20,9 +20,13 @@ FBSD_1.1 {
 FBSD_1.2 {
 } FBSD_1.1;
 
+# This version was first added to 10.0-current.
+FBSD_1.3 {
+} FBSD_1.2;
+
 # This is our private namespace.  Any global interfaces that are
 # strictly for use only by other FreeBSD applications and libraries
 # are listed here.  We use a separate namespace so we can write
 # simple ABI-checking tools.
 FBSDprivate_1.0 {
-} FBSD_1.2;
+} FBSD_1.3;

Modified: releng/7.3/lib/libc/gen/Makefile.inc
==============================================================================
--- releng/7.3/lib/libc/gen/Makefile.inc        Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.3/lib/libc/gen/Makefile.inc        Fri Dec 23 15:00:37 2011        
(r228843)
@@ -20,6 +20,7 @@ SRCS+=  __getosreldate.c __xuname.c \
        getpeereid.c getprogname.c getpwent.c getttyent.c \
        getusershell.c getvfsbyname.c glob.c \
        initgroups.c isatty.c isinf.c isnan.c jrand48.c lcong48.c \
+       libc_dlopen.c \
        lockf.c lrand48.c mrand48.c nftw.c nice.c \
        nlist.c nrand48.c opendir.c \
        pause.c pmadvise.c popen.c posixshm.c pselect.c \

Modified: releng/7.3/lib/libc/gen/Symbol.map
==============================================================================
--- releng/7.3/lib/libc/gen/Symbol.map  Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.3/lib/libc/gen/Symbol.map  Fri Dec 23 15:00:37 2011        
(r228843)
@@ -345,6 +345,10 @@ FBSD_1.2 {
        getpagesizes;
 };
 
+FBSD_1.3 {
+       __FreeBSD_libc_enter_restricted_mode;
+};
+
 FBSDprivate_1.0 {
        /* needed by thread libraries */
        __thr_jtable;

Added: releng/7.3/lib/libc/gen/libc_dlopen.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ releng/7.3/lib/libc/gen/libc_dlopen.c       Fri Dec 23 15:00:37 2011        
(r228843)
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 2011 Xin Li <delp...@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dlfcn.h>
+#include <stddef.h>
+#include <unistd.h>
+
+#include "libc_private.h"
+
+/*
+ * Whether we want to restrict dlopen()s.
+ */
+static int __libc_restricted_mode = 0;
+
+void *
+libc_dlopen(const char *path, int mode)
+{
+
+       if (__libc_restricted_mode) {
+               _rtld_error("Service unavailable -- libc in restricted mode");
+               return (NULL);
+       } else
+               return (dlopen(path, mode));
+}
+
+void
+__FreeBSD_libc_enter_restricted_mode(void)
+{
+
+       __libc_restricted_mode = 1;
+       return;
+}
+

Modified: releng/7.3/lib/libc/include/libc_private.h
==============================================================================
--- releng/7.3/lib/libc/include/libc_private.h  Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.3/lib/libc/include/libc_private.h  Fri Dec 23 15:00:37 2011        
(r228843)
@@ -44,6 +44,17 @@
 extern int     __isthreaded;
 
 /*
+ * libc should use libc_dlopen internally, which respects a global
+ * flag where loading of new shared objects can be restricted.
+ */
+void *libc_dlopen(const char *, int);
+
+/*
+ * For dynamic linker.
+ */
+void _rtld_error(const char *fmt, ...);
+
+/*
  * File lock contention is difficult to diagnose without knowing
  * where locks were set. Allow a debug library to be built which
  * records the source file and line number of each lock call.

Modified: releng/7.3/lib/libc/net/nsdispatch.c
==============================================================================
--- releng/7.3/lib/libc/net/nsdispatch.c        Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.3/lib/libc/net/nsdispatch.c        Fri Dec 23 15:00:37 2011        
(r228843)
@@ -369,7 +369,7 @@ nss_configure(void)
        confmod = statbuf.st_mtime;
 
 #ifdef NS_CACHING
-       handle = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);
+       handle = libc_dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);
        if (handle != NULL) {
                nss_cache_cycle_prevention_func = dlsym(handle,
                        "_nss_cache_cycle_prevention_function");
@@ -482,7 +482,7 @@ nss_load_module(const char *source, nss_
                if (snprintf(buf, sizeof(buf), "nss_%s.so.%d", mod.name,
                    NSS_MODULE_INTERFACE_VERSION) >= (int)sizeof(buf))
                        goto fin;
-               mod.handle = dlopen(buf, RTLD_LOCAL|RTLD_LAZY);
+               mod.handle = libc_dlopen(buf, RTLD_LOCAL|RTLD_LAZY);
                if (mod.handle == NULL) {
 #ifdef _NSS_DEBUG
                        /* This gets pretty annoying since the built-in

Modified: releng/7.3/lib/libpam/modules/pam_ssh/pam_ssh.c
==============================================================================
--- releng/7.3/lib/libpam/modules/pam_ssh/pam_ssh.c     Fri Dec 23 14:39:30 
2011        (r228842)
+++ releng/7.3/lib/libpam/modules/pam_ssh/pam_ssh.c     Fri Dec 23 15:00:37 
2011        (r228843)
@@ -88,7 +88,8 @@ static char *const pam_ssh_agent_envp[] 
  * struct pam_ssh_key containing the key and its comment.
  */
 static struct pam_ssh_key *
-pam_ssh_load_key(const char *dir, const char *kfn, const char *passphrase)
+pam_ssh_load_key(const char *dir, const char *kfn, const char *passphrase,
+    int nullok)
 {
        struct pam_ssh_key *psk;
        char fn[PATH_MAX];
@@ -98,7 +99,21 @@ pam_ssh_load_key(const char *dir, const 
        if (snprintf(fn, sizeof(fn), "%s/%s", dir, kfn) > (int)sizeof(fn))
                return (NULL);
        comment = NULL;
-       key = key_load_private(fn, passphrase, &comment);
+       /*
+        * If the key is unencrypted, OpenSSL ignores the passphrase, so
+        * it will seem like the user typed in the right one.  This allows
+        * a user to circumvent nullok by providing a dummy passphrase.
+        * Verify that the key really *is* encrypted by trying to load it
+        * with an empty passphrase, and if the key is not encrypted,
+        * accept only an empty passphrase.
+        */
+       key = key_load_private(fn, NULL, &comment);
+       if (key != NULL && !(*passphrase == '\0' && nullok)) {
+               key_free(key);
+               return (NULL);
+       }
+       if (key == NULL)
+               key = key_load_private(fn, passphrase, &comment);
        if (key == NULL) {
                openpam_log(PAM_LOG_DEBUG, "failed to load key from %s\n", fn);
                return (NULL);
@@ -165,9 +180,6 @@ pam_sm_authenticate(pam_handle_t *pamh, 
        if (pam_err != PAM_SUCCESS)
                return (pam_err);
 
-       if (*passphrase == '\0' && !nullok)
-               goto skip_keys;
-
        /* switch to user credentials */
        pam_err = openpam_borrow_cred(pamh, pwd);
        if (pam_err != PAM_SUCCESS)
@@ -175,7 +187,7 @@ pam_sm_authenticate(pam_handle_t *pamh, 
 
        /* try to load keys from all keyfiles we know of */
        for (kfn = pam_ssh_keyfiles; *kfn != NULL; ++kfn) {
-               psk = pam_ssh_load_key(pwd->pw_dir, *kfn, passphrase);
+               psk = pam_ssh_load_key(pwd->pw_dir, *kfn, passphrase, nullok);
                if (psk != NULL) {
                        pam_set_data(pamh, *kfn, psk, pam_ssh_free_key);
                        ++nkeys;
@@ -185,7 +197,6 @@ pam_sm_authenticate(pam_handle_t *pamh, 
        /* switch back to arbitrator credentials */
        openpam_restore_cred(pamh);
 
- skip_keys:
        /*
         * If we tried an old token and didn't get anything, and
         * try_first_pass was specified, try again after prompting the

Modified: releng/7.3/libexec/ftpd/ftpd.c
==============================================================================
--- releng/7.3/libexec/ftpd/ftpd.c      Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.3/libexec/ftpd/ftpd.c      Fri Dec 23 15:00:37 2011        
(r228843)
@@ -1546,6 +1546,7 @@ skip:
                        reply(550, "Can't change root.");
                        goto bad;
                }
+               __FreeBSD_libc_enter_restricted_mode();
        } else  /* real user w/o chroot */
                homedir = pw->pw_dir;
        /*

Modified: releng/7.3/libexec/ftpd/popen.c
==============================================================================
--- releng/7.3/libexec/ftpd/popen.c     Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.3/libexec/ftpd/popen.c     Fri Dec 23 15:00:37 2011        
(r228843)
@@ -142,6 +142,9 @@ ftpd_popen(char *program, char *type)
                        }
                        (void)close(pdes[1]);
                }
+               /* Drop privileges before proceeding */
+               if (getuid() != geteuid() && setuid(geteuid()) < 0)
+                       _exit(1);
                if (strcmp(gargv[0], _PATH_LS) == 0) {
                        /* Reset getopt for ls_main() */
                        optreset = optind = optopt = 1;

Modified: releng/7.3/sys/conf/newvers.sh
==============================================================================
--- releng/7.3/sys/conf/newvers.sh      Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.3/sys/conf/newvers.sh      Fri Dec 23 15:00:37 2011        
(r228843)
@@ -32,7 +32,7 @@
 
 TYPE="FreeBSD"
 REVISION="7.3"
-BRANCH="RELEASE-p8"
+BRANCH="RELEASE-p9"
 if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
        BRANCH=${BRANCH_OVERRIDE}
 fi

Modified: releng/7.4/UPDATING
==============================================================================
--- releng/7.4/UPDATING Fri Dec 23 14:39:30 2011        (r228842)
+++ releng/7.4/UPDATING Fri Dec 23 15:00:37 2011        (r228843)
@@ -8,6 +8,22 @@ Items affecting the ports and packages s
 /usr/ports/UPDATING.  Please read that file before running
 portupgrade.
 
+20111223:      p5      FreeBSD-SA-11:06.bind, FreeBSD-SA-11:07.chroot
+                       FreeBSD-SA-11:08.telnetd, FreeBSD-SA-11:09.pam_ssh
+                       FreeBSD-SA-11:10.pam
+       Fix a problem whereby a corrupt DNS record can cause named to crash.
+       [11:06]
+
+       Add an API for alerting internal libc routines to the presence of
+       "unsafe" paths post-chroot, and use it in ftpd. [11:07]
+
+       Fix a buffer overflow in telnetd. [11:08]
+
+       Make pam_ssh ignore unpassphrased keys unless the "nullok" option is
+       specified. [11:09]
+
+       Add sanity checking of service names in pam_start. [11:10]
+
 20111004:      p4      FreeBSD-SA-11:05.unix (revised)
        Fix a bug in UNIX socket handling in the linux emulator which was
        exposed by the security fix in FreeBSD-SA-11:05.unix.

Modified: releng/7.4/contrib/bind9/bin/named/query.c
==============================================================================
--- releng/7.4/contrib/bind9/bin/named/query.c  Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.4/contrib/bind9/bin/named/query.c  Fri Dec 23 15:00:37 2011        
(r228843)
@@ -1251,11 +1251,9 @@ query_addadditional(void *arg, dns_name_
                        goto addname;
                if (result == DNS_R_NCACHENXRRSET) {
                        dns_rdataset_disassociate(rdataset);
-                       /*
-                        * Negative cache entries don't have sigrdatasets.
-                        */
-                       INSIST(sigrdataset == NULL ||
-                              ! dns_rdataset_isassociated(sigrdataset));
+                       if (sigrdataset != NULL &&
+                           dns_rdataset_isassociated(sigrdataset))
+                               dns_rdataset_disassociate(sigrdataset);
                }
                if (result == ISC_R_SUCCESS) {
                        mname = NULL;
@@ -1296,8 +1294,9 @@ query_addadditional(void *arg, dns_name_
                        goto addname;
                if (result == DNS_R_NCACHENXRRSET) {
                        dns_rdataset_disassociate(rdataset);
-                       INSIST(sigrdataset == NULL ||
-                              ! dns_rdataset_isassociated(sigrdataset));
+                       if (sigrdataset != NULL &&
+                           dns_rdataset_isassociated(sigrdataset))
+                               dns_rdataset_disassociate(sigrdataset);
                }
                if (result == ISC_R_SUCCESS) {
                        mname = NULL;
@@ -1746,10 +1745,8 @@ query_addadditional2(void *arg, dns_name
                goto setcache;
        if (result == DNS_R_NCACHENXRRSET) {
                dns_rdataset_disassociate(rdataset);
-               /*
-                * Negative cache entries don't have sigrdatasets.
-                */
-               INSIST(! dns_rdataset_isassociated(sigrdataset));
+               if (dns_rdataset_isassociated(sigrdataset))
+                       dns_rdataset_disassociate(sigrdataset);
        }
        if (result == ISC_R_SUCCESS) {
                /* Remember the result as a cache */

Modified: releng/7.4/contrib/bind9/lib/dns/rbtdb.c
==============================================================================
--- releng/7.4/contrib/bind9/lib/dns/rbtdb.c    Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.4/contrib/bind9/lib/dns/rbtdb.c    Fri Dec 23 15:00:37 2011        
(r228843)
@@ -244,6 +244,7 @@ typedef struct rdatasetheader {
 #define RDATASET_ATTR_IGNORE           0x0004
 #define RDATASET_ATTR_RETAIN           0x0008
 #define RDATASET_ATTR_NXDOMAIN         0x0010
+#define RDATASET_ATTR_NEGATIVE         0x0100
 
 typedef struct acache_cbarg {
        dns_rdatasetadditional_t        type;
@@ -278,6 +279,8 @@ struct acachectl {
        (((header)->attributes & RDATASET_ATTR_RETAIN) != 0)
 #define NXDOMAIN(header) \
        (((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0)
+#define NEGATIVE(header) \
+       (((header)->attributes & RDATASET_ATTR_NEGATIVE) != 0)
 
 #define DEFAULT_NODE_LOCK_COUNT                7       /*%< Should be prime. */
 #define DEFAULT_CACHE_NODE_LOCK_COUNT  1009    /*%< Should be prime. */
@@ -3662,7 +3665,7 @@ cache_find(dns_db_t *db, dns_name_t *nam
            result == DNS_R_NCACHENXRRSET) {
                bind_rdataset(search.rbtdb, node, found, search.now,
                              rdataset);
-               if (foundsig != NULL)
+               if (!NEGATIVE(found) && foundsig != NULL)
                        bind_rdataset(search.rbtdb, node, foundsig, search.now,
                                      sigrdataset);
        }
@@ -4248,7 +4251,7 @@ cache_findrdataset(dns_db_t *db, dns_dbn
        }
        if (found != NULL) {
                bind_rdataset(rbtdb, rbtnode, found, now, rdataset);
-               if (foundsig != NULL)
+               if (!NEGATIVE(found) && foundsig != NULL)
                        bind_rdataset(rbtdb, rbtnode, foundsig, now,
                                      sigrdataset);
        }

Modified: releng/7.4/contrib/openpam/lib/openpam_configure.c
==============================================================================
--- releng/7.4/contrib/openpam/lib/openpam_configure.c  Fri Dec 23 14:39:30 
2011        (r228842)
+++ releng/7.4/contrib/openpam/lib/openpam_configure.c  Fri Dec 23 15:00:37 
2011        (r228843)
@@ -285,6 +285,13 @@ openpam_load_chain(pam_handle_t *pamh,
        size_t len;
        int r;
 
+       /* don't allow to escape from policy_path */
+       if (strchr(service, '/')) {
+               openpam_log(PAM_LOG_ERROR, "invalid service name: %s",
+                   service);
+               return (-PAM_SYSTEM_ERR);
+       }
+
        for (path = openpam_policy_path; *path != NULL; ++path) {
                len = strlen(*path);
                if ((*path)[len - 1] == '/') {

Modified: releng/7.4/contrib/telnet/libtelnet/encrypt.c
==============================================================================
--- releng/7.4/contrib/telnet/libtelnet/encrypt.c       Fri Dec 23 14:39:30 
2011        (r228842)
+++ releng/7.4/contrib/telnet/libtelnet/encrypt.c       Fri Dec 23 15:00:37 
2011        (r228843)
@@ -721,6 +721,9 @@ encrypt_keyid(struct key_info *kp, unsig
        int dir = kp->dir;
        int ret = 0;
 
+       if (len > MAXKEYLEN)
+               len = MAXKEYLEN;
+
        if (!(ep = (*kp->getcrypt)(*kp->modep))) {
                if (len == 0)
                        return;

Modified: releng/7.4/crypto/heimdal/appl/telnet/libtelnet/encrypt.c
==============================================================================
--- releng/7.4/crypto/heimdal/appl/telnet/libtelnet/encrypt.c   Fri Dec 23 
14:39:30 2011        (r228842)
+++ releng/7.4/crypto/heimdal/appl/telnet/libtelnet/encrypt.c   Fri Dec 23 
15:00:37 2011        (r228843)
@@ -736,6 +736,9 @@ encrypt_keyid(struct key_info *kp, unsig
     int dir = kp->dir;
     int ret = 0;
 
+    if (len > MAXKEYLEN)
+        len = MAXKEYLEN;
+
     if (!(ep = (*kp->getcrypt)(*kp->modep))) {
        if (len == 0)
            return;

Modified: releng/7.4/include/unistd.h
==============================================================================
--- releng/7.4/include/unistd.h Fri Dec 23 14:39:30 2011        (r228842)
+++ releng/7.4/include/unistd.h Fri Dec 23 15:00:37 2011        (r228843)
@@ -494,6 +494,7 @@ int  initgroups(const char *, gid_t);
 int     iruserok(unsigned long, int, const char *, const char *);
 int     iruserok_sa(const void *, int, int, const char *, const char *);
 int     issetugid(void);
+void   __FreeBSD_libc_enter_restricted_mode(void);
 char   *mkdtemp(char *);
 #ifndef        _MKNOD_DECLARED
 int     mknod(const char *, mode_t, dev_t);

Modified: releng/7.4/lib/libc/Versions.def
==============================================================================
--- releng/7.4/lib/libc/Versions.def    Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.4/lib/libc/Versions.def    Fri Dec 23 15:00:37 2011        
(r228843)
@@ -20,9 +20,13 @@ FBSD_1.1 {
 FBSD_1.2 {
 } FBSD_1.1;
 
+# This version was first added to 10.0-current.
+FBSD_1.3 {
+} FBSD_1.2;
+
 # This is our private namespace.  Any global interfaces that are
 # strictly for use only by other FreeBSD applications and libraries
 # are listed here.  We use a separate namespace so we can write
 # simple ABI-checking tools.
 FBSDprivate_1.0 {
-} FBSD_1.2;
+} FBSD_1.3;

Modified: releng/7.4/lib/libc/gen/Makefile.inc
==============================================================================
--- releng/7.4/lib/libc/gen/Makefile.inc        Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.4/lib/libc/gen/Makefile.inc        Fri Dec 23 15:00:37 2011        
(r228843)
@@ -20,6 +20,7 @@ SRCS+=  __getosreldate.c __xuname.c \
        getpeereid.c getprogname.c getpwent.c getttyent.c \
        getusershell.c getvfsbyname.c glob.c \
        initgroups.c isatty.c isinf.c isnan.c jrand48.c lcong48.c \
+       libc_dlopen.c \
        lockf.c lrand48.c mrand48.c nftw.c nice.c \
        nlist.c nrand48.c opendir.c \
        pause.c pmadvise.c popen.c posixshm.c pselect.c \

Modified: releng/7.4/lib/libc/gen/Symbol.map
==============================================================================
--- releng/7.4/lib/libc/gen/Symbol.map  Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.4/lib/libc/gen/Symbol.map  Fri Dec 23 15:00:37 2011        
(r228843)
@@ -345,6 +345,10 @@ FBSD_1.2 {
        getpagesizes;
 };
 
+FBSD_1.3 {
+       __FreeBSD_libc_enter_restricted_mode;
+};
+
 FBSDprivate_1.0 {
        /* needed by thread libraries */
        __thr_jtable;

Added: releng/7.4/lib/libc/gen/libc_dlopen.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ releng/7.4/lib/libc/gen/libc_dlopen.c       Fri Dec 23 15:00:37 2011        
(r228843)
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 2011 Xin Li <delp...@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <dlfcn.h>
+#include <stddef.h>
+#include <unistd.h>
+
+#include "libc_private.h"
+
+/*
+ * Whether we want to restrict dlopen()s.
+ */
+static int __libc_restricted_mode = 0;
+
+void *
+libc_dlopen(const char *path, int mode)
+{
+
+       if (__libc_restricted_mode) {
+               _rtld_error("Service unavailable -- libc in restricted mode");
+               return (NULL);
+       } else
+               return (dlopen(path, mode));
+}
+
+void
+__FreeBSD_libc_enter_restricted_mode(void)
+{
+
+       __libc_restricted_mode = 1;
+       return;
+}
+

Modified: releng/7.4/lib/libc/include/libc_private.h
==============================================================================
--- releng/7.4/lib/libc/include/libc_private.h  Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.4/lib/libc/include/libc_private.h  Fri Dec 23 15:00:37 2011        
(r228843)
@@ -44,6 +44,17 @@
 extern int     __isthreaded;
 
 /*
+ * libc should use libc_dlopen internally, which respects a global
+ * flag where loading of new shared objects can be restricted.
+ */
+void *libc_dlopen(const char *, int);
+
+/*
+ * For dynamic linker.
+ */
+void _rtld_error(const char *fmt, ...);
+
+/*
  * File lock contention is difficult to diagnose without knowing
  * where locks were set. Allow a debug library to be built which
  * records the source file and line number of each lock call.

Modified: releng/7.4/lib/libc/net/nsdispatch.c
==============================================================================
--- releng/7.4/lib/libc/net/nsdispatch.c        Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.4/lib/libc/net/nsdispatch.c        Fri Dec 23 15:00:37 2011        
(r228843)
@@ -369,7 +369,7 @@ nss_configure(void)
        confmod = statbuf.st_mtime;
 
 #ifdef NS_CACHING
-       handle = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);
+       handle = libc_dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);
        if (handle != NULL) {
                nss_cache_cycle_prevention_func = dlsym(handle,
                        "_nss_cache_cycle_prevention_function");
@@ -482,7 +482,7 @@ nss_load_module(const char *source, nss_
                if (snprintf(buf, sizeof(buf), "nss_%s.so.%d", mod.name,
                    NSS_MODULE_INTERFACE_VERSION) >= (int)sizeof(buf))
                        goto fin;
-               mod.handle = dlopen(buf, RTLD_LOCAL|RTLD_LAZY);
+               mod.handle = libc_dlopen(buf, RTLD_LOCAL|RTLD_LAZY);
                if (mod.handle == NULL) {
 #ifdef _NSS_DEBUG
                        /* This gets pretty annoying since the built-in

Modified: releng/7.4/lib/libpam/modules/pam_ssh/pam_ssh.c
==============================================================================
--- releng/7.4/lib/libpam/modules/pam_ssh/pam_ssh.c     Fri Dec 23 14:39:30 
2011        (r228842)
+++ releng/7.4/lib/libpam/modules/pam_ssh/pam_ssh.c     Fri Dec 23 15:00:37 
2011        (r228843)
@@ -88,7 +88,8 @@ static char *const pam_ssh_agent_envp[] 
  * struct pam_ssh_key containing the key and its comment.
  */
 static struct pam_ssh_key *
-pam_ssh_load_key(const char *dir, const char *kfn, const char *passphrase)
+pam_ssh_load_key(const char *dir, const char *kfn, const char *passphrase,
+    int nullok)
 {
        struct pam_ssh_key *psk;
        char fn[PATH_MAX];
@@ -98,7 +99,21 @@ pam_ssh_load_key(const char *dir, const 
        if (snprintf(fn, sizeof(fn), "%s/%s", dir, kfn) > (int)sizeof(fn))
                return (NULL);
        comment = NULL;
-       key = key_load_private(fn, passphrase, &comment);
+       /*
+        * If the key is unencrypted, OpenSSL ignores the passphrase, so
+        * it will seem like the user typed in the right one.  This allows
+        * a user to circumvent nullok by providing a dummy passphrase.
+        * Verify that the key really *is* encrypted by trying to load it
+        * with an empty passphrase, and if the key is not encrypted,
+        * accept only an empty passphrase.
+        */
+       key = key_load_private(fn, NULL, &comment);
+       if (key != NULL && !(*passphrase == '\0' && nullok)) {
+               key_free(key);
+               return (NULL);
+       }
+       if (key == NULL)
+               key = key_load_private(fn, passphrase, &comment);
        if (key == NULL) {
                openpam_log(PAM_LOG_DEBUG, "failed to load key from %s\n", fn);
                return (NULL);
@@ -165,9 +180,6 @@ pam_sm_authenticate(pam_handle_t *pamh, 
        if (pam_err != PAM_SUCCESS)
                return (pam_err);
 
-       if (*passphrase == '\0' && !nullok)
-               goto skip_keys;
-
        /* switch to user credentials */
        pam_err = openpam_borrow_cred(pamh, pwd);
        if (pam_err != PAM_SUCCESS)
@@ -175,7 +187,7 @@ pam_sm_authenticate(pam_handle_t *pamh, 
 
        /* try to load keys from all keyfiles we know of */
        for (kfn = pam_ssh_keyfiles; *kfn != NULL; ++kfn) {
-               psk = pam_ssh_load_key(pwd->pw_dir, *kfn, passphrase);
+               psk = pam_ssh_load_key(pwd->pw_dir, *kfn, passphrase, nullok);
                if (psk != NULL) {
                        pam_set_data(pamh, *kfn, psk, pam_ssh_free_key);
                        ++nkeys;
@@ -185,7 +197,6 @@ pam_sm_authenticate(pam_handle_t *pamh, 
        /* switch back to arbitrator credentials */
        openpam_restore_cred(pamh);
 
- skip_keys:
        /*
         * If we tried an old token and didn't get anything, and
         * try_first_pass was specified, try again after prompting the

Modified: releng/7.4/libexec/ftpd/ftpd.c
==============================================================================
--- releng/7.4/libexec/ftpd/ftpd.c      Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.4/libexec/ftpd/ftpd.c      Fri Dec 23 15:00:37 2011        
(r228843)
@@ -1546,6 +1546,7 @@ skip:
                        reply(550, "Can't change root.");
                        goto bad;
                }
+               __FreeBSD_libc_enter_restricted_mode();
        } else  /* real user w/o chroot */
                homedir = pw->pw_dir;
        /*

Modified: releng/7.4/libexec/ftpd/popen.c
==============================================================================
--- releng/7.4/libexec/ftpd/popen.c     Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.4/libexec/ftpd/popen.c     Fri Dec 23 15:00:37 2011        
(r228843)
@@ -143,6 +143,9 @@ ftpd_popen(char *program, char *type)
                        }
                        (void)close(pdes[1]);
                }
+               /* Drop privileges before proceeding */
+               if (getuid() != geteuid() && setuid(geteuid()) < 0)
+                       _exit(1);
                if (strcmp(gargv[0], _PATH_LS) == 0) {
                        /* Reset getopt for ls_main() */
                        optreset = optind = optopt = 1;

Modified: releng/7.4/sys/conf/newvers.sh
==============================================================================
--- releng/7.4/sys/conf/newvers.sh      Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/7.4/sys/conf/newvers.sh      Fri Dec 23 15:00:37 2011        
(r228843)
@@ -32,7 +32,7 @@
 
 TYPE="FreeBSD"
 REVISION="7.4"
-BRANCH="RELEASE-p4"
+BRANCH="RELEASE-p5"
 if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
        BRANCH=${BRANCH_OVERRIDE}
 fi

Modified: releng/8.1/UPDATING
==============================================================================
--- releng/8.1/UPDATING Fri Dec 23 14:39:30 2011        (r228842)
+++ releng/8.1/UPDATING Fri Dec 23 15:00:37 2011        (r228843)
@@ -15,6 +15,22 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.
        debugging tools present in HEAD were left in place because
        sun4v support still needs work to become production ready.
 
+20111223:      p7      FreeBSD-SA-11:06.bind, FreeBSD-SA-11:07.chroot
+                       FreeBSD-SA-11:08.telnetd, FreeBSD-SA-11:09.pam_ssh
+                       FreeBSD-SA-11:10.pam
+       Fix a problem whereby a corrupt DNS record can cause named to crash.
+       [11:06]
+
+       Add an API for alerting internal libc routines to the presence of
+       "unsafe" paths post-chroot, and use it in ftpd. [11:07]
+
+       Fix a buffer overflow in telnetd. [11:08]
+
+       Make pam_ssh ignore unpassphrased keys unless the "nullok" option is
+       specified. [11:09]
+
+       Add sanity checking of service names in pam_start. [11:10]
+
 20111004:      p6      FreeBSD-SA-11:05.unix (revised)
        Fix a bug in UNIX socket handling in the linux emulator which was
        exposed by the security fix in FreeBSD-SA-11:05.unix.

Modified: releng/8.1/contrib/bind9/bin/named/query.c
==============================================================================
--- releng/8.1/contrib/bind9/bin/named/query.c  Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/8.1/contrib/bind9/bin/named/query.c  Fri Dec 23 15:00:37 2011        
(r228843)
@@ -1282,11 +1282,9 @@ query_addadditional(void *arg, dns_name_
                        goto addname;
                if (result == DNS_R_NCACHENXRRSET) {
                        dns_rdataset_disassociate(rdataset);
-                       /*
-                        * Negative cache entries don't have sigrdatasets.
-                        */
-                       INSIST(sigrdataset == NULL ||
-                              ! dns_rdataset_isassociated(sigrdataset));
+                       if (sigrdataset != NULL &&
+                           dns_rdataset_isassociated(sigrdataset))
+                               dns_rdataset_disassociate(sigrdataset);
                }
                if (result == ISC_R_SUCCESS) {
                        mname = NULL;
@@ -1327,8 +1325,9 @@ query_addadditional(void *arg, dns_name_
                        goto addname;
                if (result == DNS_R_NCACHENXRRSET) {
                        dns_rdataset_disassociate(rdataset);
-                       INSIST(sigrdataset == NULL ||
-                              ! dns_rdataset_isassociated(sigrdataset));
+                       if (sigrdataset != NULL &&
+                           dns_rdataset_isassociated(sigrdataset))
+                               dns_rdataset_disassociate(sigrdataset);
                }
                if (result == ISC_R_SUCCESS) {
                        mname = NULL;
@@ -1777,10 +1776,8 @@ query_addadditional2(void *arg, dns_name
                goto setcache;
        if (result == DNS_R_NCACHENXRRSET) {
                dns_rdataset_disassociate(rdataset);
-               /*
-                * Negative cache entries don't have sigrdatasets.
-                */
-               INSIST(! dns_rdataset_isassociated(sigrdataset));
+               if (dns_rdataset_isassociated(sigrdataset))
+                       dns_rdataset_disassociate(sigrdataset);
        }
        if (result == ISC_R_SUCCESS) {
                /* Remember the result as a cache */

Modified: releng/8.1/contrib/bind9/lib/dns/rbtdb.c
==============================================================================
--- releng/8.1/contrib/bind9/lib/dns/rbtdb.c    Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/8.1/contrib/bind9/lib/dns/rbtdb.c    Fri Dec 23 15:00:37 2011        
(r228843)
@@ -278,6 +278,7 @@ typedef ISC_LIST(dns_rbtnode_t)         
 #define RDATASET_ATTR_RESIGN            0x0020
 #define RDATASET_ATTR_STATCOUNT         0x0040
 #define RDATASET_ATTR_OPTOUT           0x0080
+#define RDATASET_ATTR_NEGATIVE         0x0100
 
 typedef struct acache_cbarg {
        dns_rdatasetadditional_t        type;
@@ -316,6 +317,8 @@ struct acachectl {
        (((header)->attributes & RDATASET_ATTR_RESIGN) != 0)
 #define OPTOUT(header) \
        (((header)->attributes & RDATASET_ATTR_OPTOUT) != 0)
+#define NEGATIVE(header) \
+       (((header)->attributes & RDATASET_ATTR_NEGATIVE) != 0)
 
 #define DEFAULT_NODE_LOCK_COUNT         7       /*%< Should be prime. */
 
@@ -4618,7 +4621,7 @@ cache_find(dns_db_t *db, dns_name_t *nam
                              rdataset);
                if (need_headerupdate(found, search.now))
                        update = found;
-               if (foundsig != NULL) {
+               if (!NEGATIVE(found) && foundsig != NULL) {
                        bind_rdataset(search.rbtdb, node, foundsig, search.now,
                                      sigrdataset);
                        if (need_headerupdate(foundsig, search.now))
@@ -5245,7 +5248,7 @@ cache_findrdataset(dns_db_t *db, dns_dbn
        }
        if (found != NULL) {
                bind_rdataset(rbtdb, rbtnode, found, now, rdataset);
-               if (foundsig != NULL)
+               if (!NEGATIVE(found) && foundsig != NULL)
                        bind_rdataset(rbtdb, rbtnode, foundsig, now,
                                      sigrdataset);
        }

Modified: releng/8.1/contrib/openpam/lib/openpam_configure.c
==============================================================================
--- releng/8.1/contrib/openpam/lib/openpam_configure.c  Fri Dec 23 14:39:30 
2011        (r228842)
+++ releng/8.1/contrib/openpam/lib/openpam_configure.c  Fri Dec 23 15:00:37 
2011        (r228843)
@@ -285,6 +285,13 @@ openpam_load_chain(pam_handle_t *pamh,
        size_t len;
        int r;
 
+       /* don't allow to escape from policy_path */
+       if (strchr(service, '/')) {
+               openpam_log(PAM_LOG_ERROR, "invalid service name: %s",
+                   service);
+               return (-PAM_SYSTEM_ERR);
+       }
+
        for (path = openpam_policy_path; *path != NULL; ++path) {
                len = strlen(*path);
                if ((*path)[len - 1] == '/') {

Modified: releng/8.1/contrib/telnet/libtelnet/encrypt.c
==============================================================================
--- releng/8.1/contrib/telnet/libtelnet/encrypt.c       Fri Dec 23 14:39:30 
2011        (r228842)
+++ releng/8.1/contrib/telnet/libtelnet/encrypt.c       Fri Dec 23 15:00:37 
2011        (r228843)
@@ -721,6 +721,9 @@ encrypt_keyid(struct key_info *kp, unsig
        int dir = kp->dir;
        int ret = 0;
 
+       if (len > MAXKEYLEN)
+               len = MAXKEYLEN;
+
        if (!(ep = (*kp->getcrypt)(*kp->modep))) {
                if (len == 0)
                        return;

Modified: releng/8.1/crypto/heimdal/appl/telnet/libtelnet/encrypt.c
==============================================================================
--- releng/8.1/crypto/heimdal/appl/telnet/libtelnet/encrypt.c   Fri Dec 23 
14:39:30 2011        (r228842)
+++ releng/8.1/crypto/heimdal/appl/telnet/libtelnet/encrypt.c   Fri Dec 23 
15:00:37 2011        (r228843)
@@ -736,6 +736,9 @@ encrypt_keyid(struct key_info *kp, unsig
     int dir = kp->dir;
     int ret = 0;
 
+    if (len > MAXKEYLEN)
+        len = MAXKEYLEN;
+
     if (!(ep = (*kp->getcrypt)(*kp->modep))) {
        if (len == 0)
            return;

Modified: releng/8.1/include/unistd.h
==============================================================================
--- releng/8.1/include/unistd.h Fri Dec 23 14:39:30 2011        (r228842)
+++ releng/8.1/include/unistd.h Fri Dec 23 15:00:37 2011        (r228843)
@@ -513,6 +513,7 @@ int  initgroups(const char *, gid_t);
 int     iruserok(unsigned long, int, const char *, const char *);
 int     iruserok_sa(const void *, int, int, const char *, const char *);
 int     issetugid(void);
+void   __FreeBSD_libc_enter_restricted_mode(void);
 long    lpathconf(const char *, int);
 #ifndef _MKDTEMP_DECLARED
 char   *mkdtemp(char *);

Modified: releng/8.1/lib/libc/Versions.def
==============================================================================
--- releng/8.1/lib/libc/Versions.def    Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/8.1/lib/libc/Versions.def    Fri Dec 23 15:00:37 2011        
(r228843)
@@ -19,6 +19,10 @@ FBSD_1.1 {
 FBSD_1.2 {
 } FBSD_1.1;
 
+# This version was first added to 10.0-current.
+FBSD_1.3 {
+} FBSD_1.2;
+
 # This is our private namespace.  Any global interfaces that are
 # strictly for use only by other FreeBSD applications and libraries
 # are listed here.  We use a separate namespace so we can write
@@ -26,4 +30,4 @@ FBSD_1.2 {
 #
 # Please do NOT increment the version of this namespace.
 FBSDprivate_1.0 {
-} FBSD_1.2;
+} FBSD_1.3;

Modified: releng/8.1/lib/libc/gen/Makefile.inc
==============================================================================
--- releng/8.1/lib/libc/gen/Makefile.inc        Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/8.1/lib/libc/gen/Makefile.inc        Fri Dec 23 15:00:37 2011        
(r228843)
@@ -20,6 +20,7 @@ SRCS+=  __getosreldate.c __xuname.c \
        getpeereid.c getprogname.c getpwent.c getttyent.c \
        getusershell.c getvfsbyname.c glob.c \
        initgroups.c isatty.c isinf.c isnan.c jrand48.c lcong48.c \
+       libc_dlopen.c \
        lockf.c lrand48.c mrand48.c nftw.c nice.c \
        nlist.c nrand48.c opendir.c \
        pause.c pmadvise.c popen.c posix_spawn.c \

Modified: releng/8.1/lib/libc/gen/Symbol.map
==============================================================================
--- releng/8.1/lib/libc/gen/Symbol.map  Fri Dec 23 14:39:30 2011        
(r228842)
+++ releng/8.1/lib/libc/gen/Symbol.map  Fri Dec 23 15:00:37 2011        
(r228843)
@@ -369,6 +369,10 @@ FBSD_1.2 {
        getpagesizes;
 };
 
+FBSD_1.3 {
+       __FreeBSD_libc_enter_restricted_mode;
+};
+
 FBSDprivate_1.0 {
        /* needed by thread libraries */
        __thr_jtable;

Added: releng/8.1/lib/libc/gen/libc_dlopen.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ releng/8.1/lib/libc/gen/libc_dlopen.c       Fri Dec 23 15:00:37 2011        
(r228843)
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 2011 Xin Li <delp...@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to