From lrou@presto.telepluscom.net  Thu Jul 27 10:44:25 2006
Return-Path: <lrou@presto.telepluscom.net>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id DA4CF16A4DA
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 27 Jul 2006 10:44:25 +0000 (UTC)
	(envelope-from lrou@presto.telepluscom.net)
Received: from presto.telepluscom.net (presto.telepluscom.net [217.73.83.2])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 6F44E43D4C
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 27 Jul 2006 10:44:25 +0000 (GMT)
	(envelope-from lrou@presto.telepluscom.net)
Received: from presto.telepluscom.net (localhost [127.0.0.1])
	by presto.telepluscom.net (8.13.6/8.13.6) with ESMTP id k6RAiNJ6008801
	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO);
	Thu, 27 Jul 2006 12:44:23 +0200 (CEST)
	(envelope-from lrou@presto.telepluscom.net)
Received: (from lrou@localhost)
	by presto.telepluscom.net (8.13.6/8.13.6/Submit) id k6RAiNTX008800;
	Thu, 27 Jul 2006 12:44:23 +0200 (CEST)
	(envelope-from lrou)
Message-Id: <200607271044.k6RAiNTX008800@presto.telepluscom.net>
Date: Thu, 27 Jul 2006 12:44:23 +0200 (CEST)
From: Auster <lrou@presto.telepluscom.net>
Reply-To: Auster <lrou@x.ua>
To: FreeBSD-gnats-submit@freebsd.org
Cc: lrou@x.ua
Subject: libexec/tftpd: write access control
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         100914
>Category:       bin
>Synopsis:       [patch] tftpd(8): libexec/tftpd: write access control
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jul 27 10:50:11 GMT 2006
>Closed-Date:    
>Last-Modified:  Thu May 01 07:01:56 UTC 2008
>Originator:     Auster
>Release:        FreeBSD 6.1-RELEASE-p2 i386
>Organization:
>Environment:
System: FreeBSD presto.telepluscom.net 6.1-RELEASE-p2 FreeBSD 6.1-RELEASE-p2 #0: Thu Jun 15 20:30:57 CEST 2006 yx@presto.telepluscom.net:/usr/obj/usr/src/sys/presto i386

>Description:
Traditional tftp file access control:
 read access:
  tftpd(8) - tftpd will allow only publicly readable files to be accessed.
 write access:
  tftpd(8) - files may be written only if they already exist and are publicly writable.

Test condition: files may be written only if they are publicly writable (i.e. mode ??2).

Summary, libexec/tftpd write access:
 absolute filenames:
  all modes (??0 ??2 ??4) - correct.
 relative filenames:
  mode ??0 - incorrect 6.1 (RELEASE-p2 tested)
  mode ??2 - incorrect 4.11 (RELEASE-p9 tested)
  mode ??4 - incorrect both - 4.11 and 6.1


>How-To-Repeat:

for example:

~# grep '^tftp' /etc/inetd.conf
tftp	dgram	udp	wait	root	/usr/libexec/tftpd	tftpd -l -s /spool/tftp

~# touch a
~# touch /spool/tftp/a
~# chown nobody:nogroup /spool/tftp/a


1) mode ??0
~# chmod 640 /spool/tftp/a
~# tftp localhost

1a) 6.1-RELEASE-p2
tftp| put a /a
Error code 2: Access violation
  ! error - correct
tftp| put a a
  ! no error - incorrect

1b) 4.11-RELEASE-p9
tftp| put a /a
Error code 2: Access violation
  ! error - correct
tftp| put a a
Error code 2: Access violation
  ! error - correct



2) mode ??2
~# chmod 642 /spool/tftp/a
~# tftp localhost

2a) 6.1-RELEASE-p2
tftp| put a /a
  ! no error - correct
tftp| put a a
  ! no error - correct

2b) 4.11-RELEASE-p9
tftp| put a /a
  ! no error - correct
tftp| put a a
Error code 2: Access violation
  ! error - incorrect



3) mode ??4
~# chmod 644 /spool/tftp/a
~# tftp localhost

3a) 6.1-RELEASE-p2
tftp| put a /a
Error code 2: Access violation
  ! error - correct
tftp| put a a
  ! no error - incorrect

3b) 4.11-RELEASE-p9
tftp| put a /a
Error code 2: Access violation
  ! error - correct
tftp| put a a
  ! no error - incorrect



>Fix:

1) 6.1-RELEASE-p2: diff -up libexec/tftpd/tftpd.c.orig libexec/tftpd/tftpd.c
--- libexec/tftpd/tftpd.c.orig	Thu Jul 27 12:02:59 2006
+++ libexec/tftpd/tftpd.c	Thu Jul 27 12:07:57 2006
@@ -588,16 +588,28 @@ validate_access(char **filep, int mode)
 				dirp->name, filename);
 			if (stat(pathname, &stbuf) == 0 &&
 			    (stbuf.st_mode & S_IFMT) == S_IFREG) {
-				if ((stbuf.st_mode & S_IROTH) != 0) {
-					break;
+				if (mode == RRQ) {
+					if ((stbuf.st_mode & S_IROTH) != 0) {
+						break;
+					}
+				} else {
+					if ((stbuf.st_mode & S_IWOTH) != 0) {
+						break;
+					}
 				}
 				err = EACCESS;
 			}
 		}
 		if (dirp->name != NULL)
 			*filep = filename = pathname;
-		else if (mode == RRQ)
-			return (err);
+		else {
+			if (mode == RRQ) {
+				return (err);
+			} else {
+				if (!create_new)
+					return (err);
+			}
+		}
 	}
 	if (options[OPT_TSIZE].o_request) {
 		if (mode == RRQ) 



2) 4.11-RELEASE-p9: diff -up libexec/tftpd/tftpd.c.orig libexec/tftpd/tftpd.c
--- libexec/tftpd/tftpd.c.orig	Thu Jul 27 13:14:46 2006
+++ libexec/tftpd/tftpd.c	Thu Jul 27 13:17:28 2006
@@ -538,8 +538,14 @@ validate_access(char **filep, int mode)
 				dirp->name, filename);
 			if (stat(pathname, &stbuf) == 0 &&
 			    (stbuf.st_mode & S_IFMT) == S_IFREG) {
-				if ((stbuf.st_mode & S_IROTH) != 0) {
-					break;
+				if (mode == RRQ) {
+					if ((stbuf.st_mode & S_IROTH) != 0) {
+						break;
+					}
+				} else {
+					if ((stbuf.st_mode & S_IWOTH) != 0) {
+						break;
+					}
 				}
 				err = EACCESS;
 			}
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->edwin 
Responsible-Changed-By: edwin 
Responsible-Changed-When: Mon Oct 8 08:24:04 UTC 2007 
Responsible-Changed-Why:  
I'm interested in TFTP. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=100914 
Responsible-Changed-From-To: edwin->freebsd-bugs 
Responsible-Changed-By: edwin 
Responsible-Changed-When: Fri Feb 15 10:53:21 UTC 2008 
Responsible-Changed-Why:  

Give back into the pool until later. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=100914 
>Unformatted:
