Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Dec 2011 15:00:37 +0000 (UTC)
From:      Colin Percival <cperciva@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r228843 - head/contrib/telnet/libtelnet head/crypto/heimdal/appl/telnet/libtelnet head/include head/lib/libc/gen head/lib/libc/iconv head/lib/libc/include head/lib/libc/net head/libexec...
Message-ID:  <201112231500.pBNF0bEB071696@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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:
  stable/7/lib/libc/gen/libc_dlopen.c   (contents, props changed)
Modified:
  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

Changes in other areas also in this revision:
Added:
  head/lib/libc/gen/libc_dlopen.c   (contents, props changed)
  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)
  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
  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
  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: stable/7/contrib/telnet/libtelnet/encrypt.c
==============================================================================
--- stable/7/contrib/telnet/libtelnet/encrypt.c	Fri Dec 23 14:39:30 2011	(r228842)
+++ stable/7/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: stable/7/crypto/heimdal/appl/telnet/libtelnet/encrypt.c
==============================================================================
--- stable/7/crypto/heimdal/appl/telnet/libtelnet/encrypt.c	Fri Dec 23 14:39:30 2011	(r228842)
+++ stable/7/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: stable/7/include/unistd.h
==============================================================================
--- stable/7/include/unistd.h	Fri Dec 23 14:39:30 2011	(r228842)
+++ stable/7/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: stable/7/lib/libc/Versions.def
==============================================================================
--- stable/7/lib/libc/Versions.def	Fri Dec 23 14:39:30 2011	(r228842)
+++ stable/7/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: stable/7/lib/libc/gen/Makefile.inc
==============================================================================
--- stable/7/lib/libc/gen/Makefile.inc	Fri Dec 23 14:39:30 2011	(r228842)
+++ stable/7/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: stable/7/lib/libc/gen/Symbol.map
==============================================================================
--- stable/7/lib/libc/gen/Symbol.map	Fri Dec 23 14:39:30 2011	(r228842)
+++ stable/7/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: stable/7/lib/libc/gen/libc_dlopen.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/7/lib/libc/gen/libc_dlopen.c	Fri Dec 23 15:00:37 2011	(r228843)
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 2011 Xin Li <delphij@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: stable/7/lib/libc/include/libc_private.h
==============================================================================
--- stable/7/lib/libc/include/libc_private.h	Fri Dec 23 14:39:30 2011	(r228842)
+++ stable/7/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: stable/7/lib/libc/net/nsdispatch.c
==============================================================================
--- stable/7/lib/libc/net/nsdispatch.c	Fri Dec 23 14:39:30 2011	(r228842)
+++ stable/7/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: stable/7/libexec/ftpd/ftpd.c
==============================================================================
--- stable/7/libexec/ftpd/ftpd.c	Fri Dec 23 14:39:30 2011	(r228842)
+++ stable/7/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: stable/7/libexec/ftpd/popen.c
==============================================================================
--- stable/7/libexec/ftpd/popen.c	Fri Dec 23 14:39:30 2011	(r228842)
+++ stable/7/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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201112231500.pBNF0bEB071696>