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