Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watnot!watmath!clyde!rutgers!ames!ptsfa!ihnp4!oddjob!matt From: matt@oddjob.UUCP Newsgroups: comp.unix.wizards Subject: Re: tftp in 4.3BSD Message-ID: <3712@oddjob.UChicago.EDU> Date: Sat, 21-Mar-87 17:19:10 EST Article-I.D.: oddjob.3712 Posted: Sat Mar 21 17:19:10 1987 Date-Received: Sun, 22-Mar-87 23:11:14 EST References: <17946@ucbvax.BERKELEY.EDU> Reply-To: matt@oddjob.uchicago.edu (Not the kind you have to wind up on Sunday) Distribution: na Organization: Fort Mudge Perloo and Fire Brigade Lines: 98 The fact that all your public-read files become universe-read is the security hole. Certain people with more free time than manners will fetch your password file and run encryption programs until they crack some passwords. Since we need a tftp server to download our gateways, here's how I changed it. revision 1.3 date: 87/01/27 14:32:32; author: root; state: Exp; lines added/del: 11/6 Allow non-rooted pathnames if we have chroot()'d. This means we must chdir() as well as chroot(). ---------------------------- revision 1.2 date: 86/12/13 14:47:09; author: root; state: Exp; lines added/del: 7/1 If given an arg, do chroot(argv[1]). ============================================================================= RCS file: RCS/tftpd.c,v retrieving revision 1.1 retrieving revision 1.3 diff -c -r1.1 -r1.3 *** /tmp/,RCSt1029298 Sat Mar 21 16:11:45 1987 --- /tmp/,RCSt2029298 Sat Mar 21 16:11:47 1987 *************** *** 53,59 **** struct sockaddr_in from; int fromlen; ! main() { register struct tftphdr *tp; register int n; --- 53,63 ---- struct sockaddr_in from; int fromlen; ! int chrooted = 0; ! ! main(argc, argv) ! int argc; ! char *argv[]; { register struct tftphdr *tp; register int n; *************** *** 125,130 **** --- 129,140 ---- alarm(0); close(0); close(1); + if (argc > 1 && *argv[1] != '\0') + if (chdir(argv[1]) < 0 || chroot(argv[1]) < 0) { + syslog(LOG_ERR, "chroot(%s): %m\n", argv[1]); + exit(1); + } else + chrooted = 1; peer = socket(AF_INET, SOCK_DGRAM, 0); if (peer < 0) { syslog(LOG_ERR, "socket: %m\n"); *************** *** 221,227 **** * have no uid or gid, for now require * file to exist and be publicly * readable/writable. ! * Note also, full path name must be * given as we have no login directory. */ validate_access(filename, mode) --- 231,238 ---- * have no uid or gid, for now require * file to exist and be publicly * readable/writable. ! * Note also that unless we have done chroot(), ! * full path name must be * given as we have no login directory. */ validate_access(filename, mode) *************** *** 231,237 **** struct stat stbuf; int fd; ! if (*filename != '/') return (EACCESS); if (stat(filename, &stbuf) < 0) return (errno == ENOENT ? ENOTFOUND : EACCESS); --- 242,248 ---- struct stat stbuf; int fd; ! if (!chrooted && *filename != '/') return (EACCESS); if (stat(filename, &stbuf) < 0) return (errno == ENOENT ? ENOTFOUND : EACCESS); ________________________________________________________ Matt University matt@oddjob.uchicago.edu Crawford of Chicago {astrovax,ihnp4}!oddjob!matt (Footnote to correspondants: Our NSFnet connection has been dead since Wed. night.)