Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/5/84; site unmvax.UUCP Path: utzoo!watmath!clyde!burl!ulysses!mhuxj!ihnp4!zehntel!hplabs!hao!seismo!cmcl2!lanl-a!unm-cvax!unmvax!lee From: lee@unmvax.UUCP Newsgroups: net.bugs.4bsd Subject: SECURITY HOLE in tftpd Message-ID: <442@unmvax.UUCP> Date: Thu, 20-Sep-84 18:23:44 EDT Article-I.D.: unmvax.442 Posted: Thu Sep 20 18:23:44 1984 Date-Received: Wed, 26-Sep-84 04:16:21 EDT Distribution: net Organization: Univ. of New Mexico, Albuquerque Lines: 100 Here is Bill Shannon's original article.. >From shannon@sun.uucp (Bill Shannon) Sat Feb 5 23:28:16 206 >Relay-Version: version B 2.10.1 6/24/83; site unmvax.UUCP >Posting-Version: version B 2.10.1 6/24/83 SMI; site sun.uucp >Path: unmvax!unm-cvax!lanl-a!cmcl2!floyd!harpo!decvax!decwrl!sun!shannon >From: shannon@sun.uucp (Bill Shannon) >Newsgroups: net.bugs.4bsd >Subject: SECURITY HOLE in tftpd >Message-ID: <566@sun.uucp> >Date: Wed, 7-Mar-84 16:36:55 MST >Date-Received: Thu, 8-Mar-84 13:13:09 MST >Organization: Sun Microsystems, Inc. >Lines: 21 > >Subject: tftpd doesn't check file permissions properly >Index: etc/tftpd.c 4.2BSD > >Description: > The tftp daemon runs as root and is only supposed to let you > access files with public read. However, it only checks the > file itself, not the path to the file. >Repeat-By: > chmod 700 /sys > tftp localhost > get /sys/sys/tty.c >Fix: > I fixed it by doing a setgid(-2), setuid(-2) before checking access > permissions. It's hard to check the entire path by hand because > of symbolic links; you really have to run as someone who will only > have public permission to the file. -2/-2 is not guaranteed to be > restrictive enough, but it was a quick fix. Perhaps a uid/gid should > be reserved for this purpose. > > Sorry, no diff of the fix. Our tftpd has changed far too much for > other reasons for it to be useful. > I came up with a different fix that does not require a reset of the UID/GID. Nor does it need a special user id. Just runs as root. RCS file: RCS/tftpd.c,v retrieving revision 1.1 diff -c -r1.1 tftpd.c *** /tmp/,RCSt1021188 Thu Sep 20 16:22:24 1984 --- tftpd.c Thu Sep 20 16:08:43 1984 *************** *** 188,193 int mode; { struct stat stbuf; if (*file != '/') return (EACCESS); --- 188,195 ----- int mode; { struct stat stbuf; + char *ptr; + int sret; if (*file != '/') return (EACCESS); *************** *** 191,196 if (*file != '/') return (EACCESS); if (stat(file, &stbuf) < 0) return (errno == ENOENT ? ENOTFOUND : EACCESS); if (mode == RRQ) { --- 193,215 ----- if (*file != '/') return (EACCESS); + /* Check path first */ + ptr = file; + ptr++; + while (*ptr) { + if (*ptr++ != '/') + continue; + ptr--; + *ptr = NULL; + sret = stat(file, &stbuf); + *ptr++ = '/'; + if (sret < 0) + return (errno == ENOENT ? ENOTFOUND : EACCESS); + if (!((stbuf.st_mode&S_IFMT)&S_IFDIR)) + break; + if ((stbuf.st_mode&(S_IEXEC >> 6)) == 0) + return (EACCESS); + } if (stat(file, &stbuf) < 0) return (errno == ENOENT ? ENOTFOUND : EACCESS); if (mode == RRQ) { -- --Lee (Ward) {ucbvax,convex,gatech,pur-ee}!unmvax!lee