Synopsis: buffer overrun in libkrb, untrusted environment variables in telnetd
NetBSD versions: 1.5
Thanks to: Jouko Pynnönen <jouko@solutions.fi>, Assar Westerlund <assar@netbsd.org>

Index: crypto/dist/krb4/lib/krb/extra.c
===================================================================
RCS file: /cvsroot/basesrc/crypto/dist/krb4/lib/krb/extra.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -u -r1.1.1.1 -r1.1.1.1.2.1
--- crypto/dist/krb4/lib/krb/extra.c	2000/06/16 18:45:52	1.1.1.1
+++ crypto/dist/krb4/lib/krb/extra.c	2000/12/12 21:57:00	1.1.1.1.2.1
@@ -70,30 +70,6 @@
 
 #ifndef WIN32
 
-struct obsolete {
-    const char *from;
-    const char *to;
-} obsolete [] = {
-    { "KDC_TIMESYNC", "kdc_timesync" },
-    { "KRB_REVERSE_DIRECTION", "reverse_lsb_test"},
-    { "krb4_proxy", "krb4_proxy"},
-    { NULL, NULL }
-};
-    
-static void
-check_obsolete(void)
-{
-    struct obsolete *r;
-    for(r = obsolete; r->from; r++) {
-	if(getenv(r->from)) {
-	    krb_warning("The environment variable `%s' is obsolete;\n"
-			"set `%s' in your `krb.extra' file instead\n", 
-			r->from, r->to);
-	    define_variable(r->to, getenv(r->from));
-	}
-    }
-}
-
 static int
 read_extra_file(void)
 {
@@ -103,7 +79,6 @@
     if(_krb_extra_read)
 	return 0;
     _krb_extra_read = 1;
-    check_obsolete();
     while(krb_get_krbextra(i++, file, sizeof(file)) == 0) {
 	FILE *f = fopen(file, "r");
 	if(f == NULL)
Index: crypto/dist/krb4/lib/krb/kdc_reply.c
===================================================================
RCS file: /cvsroot/basesrc/crypto/dist/krb4/lib/krb/kdc_reply.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -u -r1.1.1.1 -r1.1.1.1.2.1
--- crypto/dist/krb4/lib/krb/kdc_reply.c	2000/06/16 18:45:53	1.1.1.1
+++ crypto/dist/krb4/lib/krb/kdc_reply.c	2000/12/12 21:56:37	1.1.1.1.2.1
@@ -121,6 +121,9 @@
     p += krb_get_int(p, &exp_date, 4, little_endian);
     p++; /* master key version number */
     p += krb_get_int(p, &clen, 2, little_endian);
+    if (reply->length - (p - reply->dat) < clen)
+	return INTK_PROT;
+
     cip->length = clen;
     memcpy(cip->dat, p, clen);
     p += clen;
Index: crypto/dist/krb4/lib/krb/tf_util.c
===================================================================
RCS file: /cvsroot/basesrc/crypto/dist/krb4/lib/krb/tf_util.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -u -u -r1.1.1.1 -r1.1.1.1.2.1
--- crypto/dist/krb4/lib/krb/tf_util.c	2000/06/16 18:45:56	1.1.1.1
+++ crypto/dist/krb4/lib/krb/tf_util.c	2000/12/12 21:56:15	1.1.1.1.2.1
@@ -249,20 +249,6 @@
 int
 tf_create(char *tf_name)
 {
-  struct stat statbuf;
-  char garbage[BUFSIZ];
-
-  fd = open(tf_name, O_RDWR | O_BINARY, 0);
-  if (fd >= 0) {
-    if (fstat (fd, &statbuf) == 0) {
-      int i;
-
-      for (i = 0; i < statbuf.st_size; i += sizeof(garbage))
-	write (fd, garbage, sizeof(garbage));
-    }
-    close (fd);
-  }
-
   if (unlink (tf_name) && errno != ENOENT)
     return TKT_FIL_ACC;
 
Index: libexec/telnetd/sys_term.c
===================================================================
RCS file: /cvsroot/basesrc/libexec/telnetd/sys_term.c,v
retrieving revision 1.18
retrieving revision 1.18.4.2
diff -u -u -r1.18 -r1.18.4.2
--- libexec/telnetd/sys_term.c	1999/12/31 12:42:35	1.18
+++ libexec/telnetd/sys_term.c	2000/12/15 00:37:19	1.18.4.2
@@ -1881,22 +1881,50 @@
 /*
  * scrub_env()
  *
- * Remove a few things from the environment that
- * don't need to be there.
+ * We only accept the environment variables listed below.
  */
+
 void
 scrub_env()
 {
-	register char **cpp, **cpp2;
+	static const char *reject[] = {
+		"TERMCAP=/",
+		NULL
+	};
+
+	static const char *accept[] = {
+		"XAUTH=", "XAUTHORITY=", "DISPLAY=",
+		"TERM=",
+		"EDITOR=",
+		"PAGER=",
+		"LOGNAME=",
+		"POSIXLY_CORRECT=",
+		"TERMCAP=",
+		"PRINTER=",
+		NULL
+	};
+
+	char **cpp, **cpp2;
+	const char **p;
 
 	for (cpp2 = cpp = environ; *cpp; cpp++) {
-		if (strncmp(*cpp, "LD_", 3) &&
-		    strncmp(*cpp, "_RLD_", 5) &&
-		    strncmp(*cpp, "LIBPATH=", 8) &&
-		    strncmp(*cpp, "IFS=", 4))
+		int reject_it = 0;
+
+		for(p = reject; *p; p++)
+			if(strncmp(*cpp, *p, strlen(*p)) == 0) {
+				reject_it = 1;
+				break;
+			}
+		if (reject_it)
+			continue;
+
+		for(p = accept; *p; p++)
+			if(strncmp(*cpp, *p, strlen(*p)) == 0)
+				break;
+		if(*p != NULL)
 			*cpp2++ = *cpp;
 	}
-	*cpp2 = 0;
+	*cpp2 = NULL;
 }
 
 /*