From owner-freebsd-bugs@FreeBSD.ORG Thu Jul 27 10:50:13 2006 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B821B16A4DF for ; Thu, 27 Jul 2006 10:50:13 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1EC0243D4C for ; Thu, 27 Jul 2006 10:50:13 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id k6RAoC1F019696 for ; Thu, 27 Jul 2006 10:50:12 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id k6RAoC7J019695; Thu, 27 Jul 2006 10:50:12 GMT (envelope-from gnats) Resent-Date: Thu, 27 Jul 2006 10:50:12 GMT Resent-Message-Id: <200607271050.k6RAoC7J019695@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Auster Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id DA4CF16A4DA for ; 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 ; 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 To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: lrou@x.ua Subject: bin/100914: libexec/tftpd: write access control X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Auster List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 27 Jul 2006 10:50:13 -0000 >Number: 100914 >Category: bin >Synopsis: 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: >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: >Unformatted: