From f813782276c9c93ba7fdca9011c120626dce86e4 Mon Sep 17 00:00:00 2001 From: Simon Schubert Date: Sat, 14 Feb 2009 13:00:50 +0100 Subject: [PATCH] telnetd: filter potentially dangerous env vars passed from telnet client Obtained-from: NetBSD revision 1.6 date: 1995-10-18 06:44:26 +0100 Reported-by: Trevor Kendall --- libexec/telnetd/state.c | 64 ++++++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/libexec/telnetd/state.c b/libexec/telnetd/state.c index 576eb12dcb..d4547fa3f1 100644 --- a/libexec/telnetd/state.c +++ b/libexec/telnetd/state.c @@ -38,6 +38,8 @@ #include #include "telnetd.h" +static int envvarok(char *); + unsigned char doopt[] = { IAC, DO, '%', 'c', 0 }; unsigned char dont[] = { IAC, DONT, '%', 'c', 0 }; unsigned char will[] = { IAC, WILL, '%', 'c', 0 }; @@ -990,6 +992,44 @@ int env_ovalue = -1; # define env_ovalue OLD_ENV_VALUE #endif /* ENV_HACK */ +/* envvarok(char*) */ +/* check that variable is safe to pass to login or shell */ +static int +envvarok(char *varp) +{ + + if (strcmp(varp, "TERMCAP") && /* to prevent a security hole */ + strcmp(varp, "TERMINFO") && /* with tgetent */ + strcmp(varp, "TERMPATH") && + strcmp(varp, "HOME") && /* to prevent the tegetent bug */ + strncmp(varp, "LD_", strlen("LD_")) && /* most systems */ + strncmp(varp, "_RLD_", strlen("_RLD_")) && /* IRIX */ + strcmp(varp, "LIBPATH") && /* AIX */ + strcmp(varp, "ENV") && + strcmp(varp, "BASH_ENV") && + strcmp(varp, "IFS") && + strncmp(varp, "KRB5", strlen("KRB5")) && /* Krb5 */ + /* + * The above case is a catch-all for now. Here are some of + * the specific ones we must avoid passing, at least until + * we can prove it can be done safely. Keep this list + * around un case someone wants to remove the catch-all. + */ + strcmp(varp, "KRB5_CONFIG") && /* Krb5 */ + strcmp(varp, "KRB5CCNAME") && /* Krb5 */ + strcmp(varp, "KRB5_KTNAME") && /* Krb5 */ + strcmp(varp, "KRBTKFILE") && /* Krb4 */ + strcmp(varp, "KRB_CONF") && /* CNS 4 */ + strcmp(varp, "KRB_REALMS") && /* CNS 4 */ + strcmp(varp, "RESOLV_HOST_CONF")) /* Linux */ + return (1); + else { + syslog(LOG_INFO, "Rejected the attempt to modify the " + "environment variable \"%s\"", varp); + return (0); + } +} + /* * suboption() * @@ -1328,12 +1368,14 @@ suboption(void) case NEW_ENV_VAR: case ENV_USERVAR: *cp = '\0'; - if (valp) { - if (setenv(varp, valp, 1) == -1) - syslog(LOG_ERR, "setenv: cannot set %s=%s: %m", varp, valp); + if (envvarok(varp)) { + if (valp) { + if (setenv(varp, valp, 1) == -1) + syslog(LOG_ERR, "setenv: cannot set %s=%s: %m", varp, valp); + } + else + unsetenv(varp); } - else - unsetenv(varp); cp = varp = (char *)subpointer; valp = 0; break; @@ -1349,12 +1391,14 @@ suboption(void) } } *cp = '\0'; - if (valp) { - if (setenv(varp, valp, 1) == -1) - syslog(LOG_ERR, "setenv: cannot set %s=%s: %m", varp, valp); + if (envvarok(varp)) { + if (valp) { + if (setenv(varp, valp, 1) == -1) + syslog(LOG_ERR, "setenv: cannot set %s=%s: %m", varp, valp); + } + else + unsetenv(varp); } - else - unsetenv(varp); break; } /* end of case TELOPT_NEW_ENVIRON */ -- 2.41.0