Subject: ftpd security fix, setenv documentation error Index: libexec/ftpd/ftpd.c,man/man3/getenv.3,lint/llib-lc 2.11BSD Description: 1. There is a security problem in ftpd if it is compiled to use setproctitle() to show the state of the transfer in the 'ps' output. 2. The documentation for setenv(3) mistakenly specifies the second argument as 'char' rather than 'char *'. The lint library for libc propagated this error. Repeat-By: 1. The setproctitle() bug is fairly widely known. Ftpd can be tricked with percent ('%') characters in the user supplied data (filenames) and do nasty things. The fix is to avoid having ftpd being fooled into using the supplied data as a printf format string ('%s' for example). 2. Observation. The second argument to setenv(3) obviously has to be a 'char *'. If one believed the documentation then a program would coredump or otherwise misbehave. Fix: The following files are updated by this patch: /usr/src/libexec/ftpd/ftpd.c /usr/src/man/man3/getenv.3 /usr/share/lint/llib-lc /VERSION Cut where indicated and save to a file (/tmp/436). Then patch -p0 < /tmp/436 cd /usr/src/libexec/ftpd make make install make clean cd /usr/src/usr.bin/lint ./libs cd /usr/src/man/man3 /usr/man/manroff getenv.3 > /usr/man/cat3/getenv.0 The manpages for getenv(3), setenv(3), and unsetenv(3) are hardlinks to each other so updating any one of them updates all of them. As always this and previous updates to 2.11BSD are available via anonymous FTP to either FTP.TO.GD-ES.COM or MOE.2BSD.COM in the directory /pub/2.11BSD. ------------------------cut here------------------ *** /usr/src/libexec/ftpd/ftpd.c.old Fri Mar 22 22:43:24 1996 --- /usr/src/libexec/ftpd/ftpd.c Thu Apr 26 19:36:30 2001 *************** *** 20,26 **** "@(#) Copyright (c) 1985, 1988 Regents of the University of California.\n\ All rights reserved.\n"; ! static char sccsid[] = "@(#)ftpd.c 5.28.2 (2.11BSD) 1996/3/22"; #endif /* --- 20,26 ---- "@(#) Copyright (c) 1985, 1988 Regents of the University of California.\n\ All rights reserved.\n"; ! static char sccsid[] = "@(#)ftpd.c 5.28.3 (2.11BSD) 2001/4/26"; #endif /* *************** *** 476,482 **** sprintf(proctitle, "%s: anonymous/%.*s", remotehost, sizeof(proctitle) - sizeof(remotehost) - sizeof(": anonymous/"), passwd); ! setproctitle(proctitle); #endif /* SETPROCTITLE */ if (logging) syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s, %s", --- 476,482 ---- sprintf(proctitle, "%s: anonymous/%.*s", remotehost, sizeof(proctitle) - sizeof(remotehost) - sizeof(": anonymous/"), passwd); ! setproctitle("%s", proctitle); #endif /* SETPROCTITLE */ if (logging) syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s, %s", *************** *** 485,491 **** reply(230, "User %s logged in.", pw->pw_name); #ifdef SETPROCTITLE sprintf(proctitle, "%s: %s", remotehost, pw->pw_name); ! setproctitle(proctitle); #endif /* SETPROCTITLE */ if (logging) syslog(LOG_INFO, "FTP LOGIN FROM %s, %s", --- 485,491 ---- reply(230, "User %s logged in.", pw->pw_name); #ifdef SETPROCTITLE sprintf(proctitle, "%s: %s", remotehost, pw->pw_name); ! setproctitle("%s", proctitle); #endif /* SETPROCTITLE */ if (logging) syslog(LOG_INFO, "FTP LOGIN FROM %s, %s", *************** *** 1133,1139 **** sizeof (remotehost)); #ifdef SETPROCTITLE sprintf(proctitle, "%s: connected", remotehost); ! setproctitle(proctitle); #endif /* SETPROCTITLE */ if (logging) { --- 1133,1139 ---- sizeof (remotehost)); #ifdef SETPROCTITLE sprintf(proctitle, "%s: connected", remotehost); ! setproctitle("%s", proctitle); #endif /* SETPROCTITLE */ if (logging) { *** /usr/src/man/man3/getenv.3.old Mon Mar 30 16:52:45 1987 --- /usr/src/man/man3/getenv.3 Thu Feb 22 19:48:44 2001 *************** *** 1,6 **** ! .\" @(#)getenv.3 6.4 (Berkeley) 3/20/87 .\" ! .TH GETENV 3 "March 20, 1987" .AT 3 .SH NAME getenv, setenv, unsetenv \- manipulate environmental variables --- 1,6 ---- ! .\" @(#)getenv.3 6.4.1 (2.11BSD) 2001/2/22 .\" ! .TH GETENV 3 "February 22, 2001" .AT 3 .SH NAME getenv, setenv, unsetenv \- manipulate environmental variables *************** *** 10,16 **** .B char *name; .PP .B setenv(name, value, overwrite) ! .B char *name, value; .B int overwrite; .PP .B void unsetenv(name) --- 10,16 ---- .B char *name; .PP .B setenv(name, value, overwrite) ! .B char *name, *value; .B int overwrite; .PP .B void unsetenv(name) *** /usr/share/lint/llib-lc.old Mon Feb 28 20:49:45 2000 --- /usr/share/lint/llib-lc Thu Feb 22 19:52:02 2001 *************** *** 1,4 **** ! /* @(#)llib-lc 1.47 (2.11BSD) 1999/9/9 */ /* LINTLIBRARY */ --- 1,4 ---- ! /* @(#)llib-lc 1.48 (2.11BSD) 2001/2/22 */ /* LINTLIBRARY */ *************** *** 345,351 **** { return 1; } void seekdir( p, l) DIR *p; long l; {} int setegid(egid) gid_t egid; { return 0; } ! int setenv(n, v, o) char *n, v; { return 0; } int seteuid(euid) uid_t euid; { return 0; } int setfsent() { return 0; } --- 345,351 ---- { return 1; } void seekdir( p, l) DIR *p; long l; {} int setegid(egid) gid_t egid; { return 0; } ! int setenv(n, v, o) char *n, *v; { return 0; } int seteuid(euid) uid_t euid; { return 0; } int setfsent() { return 0; } *** /VERSION.old Wed Feb 7 20:56:59 2001 --- /VERSION Thu Apr 26 19:36:22 2001 *************** *** 1,5 **** ! Current Patch Level: 435 ! Date: February 7, 2001 2.11 BSD ============ --- 1,5 ---- ! Current Patch Level: 436 ! Date: April 26, 2001 2.11 BSD ============