Synopsis: buffer overrun in libkrb, untrusted environment variables in telnetd
NetBSD versions: 1.5
Thanks to: Jouko Pynn�nen <[email protected]>, Assar Westerlund <[email protected]>

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;
}

/*